Promise是什么?
promise是js处理异步编程的解决方案。
具体表达:
从语法上来说,promise是一个构造函数
从功能上来说,promise对象用来封装一个异步操作并可以获取其结果。
Promise的状态改变。
1.pending 变为 resolved。
2.pedning 变为 rejected。
说明:promise对象只能改变一次,无论成功还是失败,都会有一个结果数据。
成功的结果数据一般称为value,失败的结果数据一般称为reason(原因)
Promise的基本流程
Promise的基本使用
// 1.创建一个peomise对象
const p = new Promise((resolve, reject) => {
// 2.执行异步操作
setTimeout(() => {
const time = Date.now()
// 3.1 如果成功了,调用resolve(value)
if (time % 2 == 0) {
resolve('success'+ time)
} else {
// 3.2 如果失败了,调用reject(reason)
reject('error' + time)
}
}, 1000)
})
p.then(
value => { //接收得到成功的value数据
console.log('success11',value)
},
reason => { //接收得到失败的reason数据
console.log('error11',reason)
}
)
为什么用Promise?
1.指定回调函数的方式更加灵活。
2.支持链式调用,可以解决回调地狱的问题。
什么是回调地狱:回调函数嵌套调用,外部回调函数异步执行的结果是嵌套的回调函数的执行条件。
回调地狱的特点:不便于阅读 / 不便于异常处理。
解决方案:async + await
如何使用Promise?
Promise.resolve() Promise.reject()的使用
const p1 = new Promise((resolve,reject)=>{
resolve(1)
})
const p2 = Promise.resolve(2)
const p3 = Promise.reject(3)
p1.then(value=>{
console.log(value)
})
p2.then(value=>{
console.log(value)
})
p3.catch(reason=>{
console.log(reason)
})
//打印结果 1 2 3
Promise.all() Promise.race()的使用
Promise.all() 接收参数是一个数组,数组内是promise对象,必须都成功才会返回成功
Promise.race() 传的也是一个数组promise对象,判断第一个是否成功
第一个promise对象成功返回成功,第一个失败返回失败
并不是谁先前面就是谁,得先看哪个promise先执行完毕
完整练习代码展示
const p1 = new Promise((resolve,reject)=>{
resolve(1)
})
const p2 = Promise.resolve(2)
const p3 = Promise.reject(3)
p1.then(value=>{
console.log(value)
})
p2.then(value=>{
console.log(value)
})
p3.catch(reason=>{
console.log(reason)
})
//打印结果 1 2 3
// Promise.all 接收参数是一个数组,数组内是promise对象
// 必须都成功才会返回成功
const pAll = Promise.all([p1,p2,p3])
const pAll1 = Promise.all([p1,p2])
pAll.then(
values=>{
console.log('all onResolved()',values)
},
reason=>{
console.log('all onRejected()',reason)
// 打印结果 all onRejected() 3
}
)
pAll1.then(
values=>{
console.log('all onResolved()',values)
// 打印结果是一个数组 [1,2]
},
reason=>{
console.log('all onRejected()',reason)
}
)
// Promise.race()传的也是一个数组promise对象,判断第一个是否成功
// 第一个promise对象成功返回成功,第一个失败返回失败
// 并不是谁先前面就是谁,得先看哪个promise先执行完毕
const pRace = Promise.race([p1,p2,p3])
pRace.then(
values=>{
console.log('race onResolved()',values)
// 打印结果 race onResolved() 1
},
reason=>{
console.log('race onRejected()',reason)
}
)
promise几个常见问题解析。
1.如何改变promise的状态。
-
1.resolve(value):如果当前是pendding就会变成resolved
-
2.reject(reason):如果当前是pendding就会变成rejected
-
3.抛出异常:如果当前是pendding就会变成rejected
**代码解析 **
const p = new Promise((resolve,reject)=>{
// resolve(1)
// reject(2)
throw new Error('error');//抛出异常,promise状态变为reject失败状态,reason为抛出的error。
// throw 3 //3 "reason"
})
p.then(
value=>{
},
reason=>{
console.log(reason,'reason')
}
)
2. 一个promise指定多个成功/失败的回调函数都会被调用吗?
当promise改变未对应状态的时候都会调用
代码解析
两个then报错的地方都会打印出来
const p = new Promise((resolve, reject) => {
// resolve(1)
// reject(2)
// throw new Error('error');//抛出异常,promise状态变为reject失败状态,reason为抛出的error。
throw 3 //3 "reason"
})
p.then(
value => {
},
reason => {
console.log(reason, 'reason')
}
)
p.then(
value => {
},
reason => {
console.log(reason, 'reason2')
}
)
** 3.改变promise状态和指定回调函数,谁先谁后?**
-
1.都有可能,正常情况下先指定回调函数再改变状态,但也可以先改变状态再执行回调。
-
2.如何先改状态再执行回调? * 1.在执行器中直接调用resolve()/reject() * 2.延迟更长事件才调用then()
-
3.什么时候才能得到数据?
-
1.如果先指定的回调:那么当状态发生改变时,回调函数就会调用,得到数据
-
2.如果先改变的状态:那当指定回调时,回调函数就会调用,得到数据
常规: 先指定回调函数 后改变promise状态
// 常规: 先指定回调函数 后改变promise状态
new Promise((resolve, reject) => {
setTimeout(() => {
resolve(1) //后改变状态(同时指定数据),异步执行回调函数
}, 1000)
}).then( // 先指定回调函数,保存当前指定的回调函数
value => {},
reason => {}
)
先改变promise状态 后指定回调函数
// 先改变promise状态 后指定回调函数
new Promise((resolve, reject) => {
resolve(1) //先改变状态(同时指定数据)
}).then( // 后指定回调函数,异步执行回调函数
value => {console.log(value, 'value')},
reason => {console.log(reason, 'reason')}
)
4. promise.then()返回的新promise的结果状态由什么决定?
**简单描述:由then()指定的回调函数执行的结果决定 **
来看一下下面的代码输出的是什么?想一想为什么?
new Promise((resolve, reject) => {
resolve(1)
}).then(
value => {console.log(value, 'resolve1')},
reason => {console.log(reason, 'reject1')}
).then(
value => {console.log(value, 'resolve2')},
reason => {console.log(reason, 'reject2')}
)
答案输出的是
1 "resolve1"
undefined "resolve2"
再来看一下 下面的代码输出什么??
new Promise((resolve, reject) => {
// resolve(1)
reject(1)
}).then(
value => {console.log(value, 'resolve1')},
reason => {console.log(reason, 'reject1')}
).then(
value => {console.log(value, 'resolve2')},
reason => {console.log(reason, 'reject2')}
)
答案是:
1 "reject1"
undefined "resolve2"
再来看一下 下面的代码输出什么??
new Promise((resolve, reject) => {
resolve(1)
}).then(
value => {
console.log(value, 'resolve1')
return 3
},
reason => {console.log(reason, 'reject1')}
).then(
value => {console.log(value, 'resolve2')},
reason => {console.log(reason, 'reject2')}
)
答案是:
** 1 "resolve1"**
** 3 "resolve2"**
看出来是什么原因了嘛?想一想,再看下面的代码
new Promise((resolve, reject) => {
resolve(1)
}).then(
value => {
console.log(value, 'resolve1')
// return 3
// return Promise.resolve(4);
// return Promise.reject(5);
throw 6
},
reason => {console.log(reason, 'reject1')}
).then(
value => {console.log(value, 'resolve2')},
reason => {console.log(reason, 'reject2')}
)
可以运行一下代码,改变value中的注释,看看输出的结果。。
详细解释:
1.如果抛出异常,新promise变为rejected reason为抛出的异常
2.如果返回的是非promise的任意值,新promise变为resolved,value为返回的值。
3.如果返回的是另一个promise,此promise的结果就会成为新promise的结果。
5. promise如何串联多个操作任务?
1. promise的then()返回一个新的promise对象,可以通过then()的链式调用。
2. 通过then的链式调用串多个同步/异步任务
搞个练习,下面代码的输出顺序是什么?
图片看着方便一些,代码在下面,可以复制运行看一下结果跟自己想的是否一样
new Promise((resolve, reject) => {
setTimeout(() => {
console.log('执行异步任务1')
resolve(1)
}, 1000)
}).then(
value => {
console.log(value, '任务1的结果')
console.log('执行同步任务2')
// 同步操作,只需要return 一个结果就好
return 2
},
).then(
value => {
console.log(value, '任务2的结果')
// 异步操作,需要return 一个新的promise对象,用promise的结果作为返回值
return new Promise((resolve, reject) => {
setTimeout(() => {
console.log('执行异步任务3')
resolve(3)
}, 1000)
})
},
).then(
value=>{
console.log(value, '任务3的结果')
}
)
答案:
执行异步任务1
1 "任务1的结果"
执行同步任务2
2 "任务2的结果"
3 执行异步任务3
3 "任务3的结果"
6. promise异常穿透?
当使用promise中的then链式调用时,可以在最后指定失败的回调。
前面任何操作出了异常,都会传到最后失败的回调中处理。
下图输出什么?
答案是
** resolve1 1**
** resolve2 2**
** resolve3 3**
改变一行代码,看下图输出什么
答案是
** rejected 1**
为什么呢?是一步一步的向下传递
看下图
6. 中断promise链?
当使用promise中的then链式调用时,在中间中断,不再调用后面的回调函数。
办法:在回调函数中返回一个pendding状态的promise对象。
下图代码输出什么?
答案是:
rejected 1
resolve4 undefined
现在我想让最后一个then里面的promise不执行,该怎么操作呢?
看下图//这就是终端promise链