异步回调的问题
- 嵌套层次深,难以维护
- 无法正常使用return 和 throw
- 无法正常检索堆栈信息
- 多个回调之间难以建立联系
promise定义
new Promise(
/* 执行器 executor */
function(resolve, reject){
// 一段耗时很长的异步操作
resolve(); // 数据处理完成
reject(); //数据处理出错
}
)
.then(function A(){
// 成功,下一步
}, function B(){
// 失败,做相应处理
});
解释:初始化promise实例的时候,传入一个函数作为参数,该函数称为执行器。执行器函数有两个函数参数:resolve和reject,执行器中用来执行耗时的操作,如果该操作处理成功,调用resolve,处理失败调用reject。resolve和reject的调用会改变promise的状态,promise状态改变后调用then函数,并根据promise是fulfilled状态还是rejected状态,来决定调用then的第一个函数还是第二个函数。
可见,promise是一个代理对象,与原本的操作并无关系,通过引入一组回调,避免了更多的回调。
promise流程图
.then()
then函数中可返回一个promise实例,然后根据该promise实例的完成状态,调用下一个then函数,完成promise的链式调用。
若then函数没有返回promise实例,则下一个then会立即执行。
we have a problem with promises
注:doSomething 和 doSomethingElse 都是promise实例。
问题1:then函数返回了一个promise实例。
问题2:虽然doSomethingElse返回一个promise实例,但是这个实例并没有返回给then的函数,所以第一个then相当于返回了空。
问题3:第一个then中传入doSomethingElse,但是注意,是以立即执行的方式传入的,所以doSomething和doSomethingElse是一起执行的。因为doSomethingElse返回的是一个promise实例,而不是一个函数,因此根据promise定义的规范,这个then会被忽略,而第二个then侦听的是第一个promise的完成时间和参数。
问题4:then中正常传入一个函数作为参数。
promise错误处理
promise的错误处理有 catch 和 then 两种方式。then的第二个函数用来处理promise的rejected状态。而catch只是promise.then(undefined, onRejected)方法的一个别名而已,也就是说,这个方法用来注册当promise对象状态变为rejected时的回调函数。
Promise常用函数
Promise.all()
- Promise.all([p1, p2, p3, …]) 批量执行多个promise实例,返回普通promise实例。
- 当所有子promise完成,promise.all()完成,返回值为数组,是子promise的执行结果。任何一个子promise失败,都会导致promise.all()失败,返回值为第一个失败的promise的返回值。
- promise.all()的数组参数可以是promise,也可以是其他值。
Promise.race()
- Promise.race() 中任何一个子promise完成,promise.race()就完成。