JavaScript Promise迷你书

对象方法与实例方法的表示

实例方法:Promise#then,表示为Promise的实例对象的then方法 对象方法:Promise.all,表示为Promise类的静态方法

1. 什么是Promise

1.1 构造器

var promise = new Promise((resolve, reject) {
    // 异步处理
    // 处理结束之后调用resolve或者reject
})

1.2 实例方法

promise.then(onFulfilled, onRejected) 当resolve(成功)时,onFulfilled会被调用, 当reject(失败)时,onRejected会被调用。

promise.then 在成功和失败时都可以调用,如果只想处理异常情况,可以使用 promise.then(undefined, onRejected),即只指定reject的回调函数。

不过这种情况下promise.catch(onRejected)应该是更好的选择,即推荐使用.catch来将 resolvereject 处理分开来写,而不是使用 .then(onResolve,onReject)

new Promise((resolve,reject) => {
  return (2)
  resolve(1);
}).then(res => {
  console.log(res)  //  不打印,promise一直是pending
})

new Promise((resolve,reject) => {
  resolve(1);
  return (2)
}).then(res => {
  console.log(res) //  打印1, 与return的值无关
})

new Promise((resolve,reject) => {
  reject(1);
  return (2)
}).then(res => {
  console.log(res)
},(ee) => {
  console.log("@@",ee)         // 打印 1,即错误由这里捕获
}).catch((err) => {
  console.log(err)             // 不打印
})

1.3 静态方法

Promise.all()Promise.resolve()Promise.reject()

1.4 promise的状态

promise的三种状态:Fulfilled, Rejected, Pending .暂时没有查询其内部状态的方法。

promise对象的状态从 pending 转为 fulfilled 或者 rejected 之后,这个对象的状态就不会再发生任何变化,即 .then 后执行的函数之后被调用一次。

2. 实战 Promise

2.1 创建promise对象

一般情况下可以使用 new Promise()来创建promise对象,同时还可以使用Promise.resolve()Promise.reject()这两个方法。

Promise.resolve(42) 可以认为是以下代码的语法糖:

Promise.resolve(value) 返回值也是一个 promise对象 ,因此可以使用.then进行调用。

Promise.resolve 作为 new Promise() 的快捷方式,在进行promise对象的初始化或者编写测试代码时都非常方便。

2.2 thenable

Promise.resolve 的另一个作用就是将 thenable(即,拥有.then方法) 的对象转换为 promise 对象。

这种将 thenable对象 转换为 promise对象 的机制要求 thenable对象 所拥有的 then 方法与 Promise 对象的 then 方法具有相同的功能和处理过程。

jQuery.ajax()返回值就是 thenable 的,因为该返回值是 jqXHR Object 对象,具有 .then 方法。

即转换为 promise 对象之后,就能直接使用 then 或者 catch 等方法了。

2.3 Promise.reject()

Promise.reject(error) 也是 new Promise() 方法的快捷方式。Promise.reject(new Error('error')) 是下面代码的语法糖:

2.4 Promise只能进行异步操作

2.5 try catch 不能捕获异步的error

2.6 方法链 Promise#then

2.7 异常处理

即当 taskA 或者 taskB 中出现异常(这种异常可以是 throw一个error ,或者返回一个 rejected状态的promise对象 ),都会进入 onRejected 处理。

由于在 onRejectedfinalTask 两个任务后面没有 catch 处理,因此如果在这两个任务出现异常,将不会被捕获。

2.8 Promise#then 参数传递

如果两个任务之间要进行值的传递,则需要在上一个任务中将值 return 出来

2.9 Promise#catch

Promise#catch 只是 Promise#then(undefined,onRejected) 方法的别名,即当 promise对象 状态变为 Rejected 时的回调。

2.10 then 和 catch 都是返回新的 promise 对象

2.11 Promise.all 与 Promise.race

Promise.all: 当数组里所有的 promise对象 全部变为 resolve或reject状态 的时候,才会调用 .then 方法。如下,即最长时间 128ms 之后,才会执行 .then

Promise.race(): 只要有 一个promise对象 变为 fulfilled 或者 rejected 状态,就会调用后续的 .then 或者 .catch 处理。如下:

4ms之后 第一个promise 进行 resolve ,因此 Promise.race 进行后续的处理。但是 loserPromise 这个 promise 依然会执行,并不会因为 race 而被取消。

2.12 使用 .then(undefined, onRejected) 还是 .catch(onRejected)

即如果使用 then 的方式,如果 onFulfilled 中抛出异常,是不能被当前的 onRejected 捕获的,因此使用 .catch 是更好的处理错误方式。

3. Promise Advanced

Promises/A+ES6 Promises 的前身,如果一个类库兼容 Promise/A+ 的话,那么说明除了 then 方法之外,还支持 Promise.all和catch

3.1 类库 bluebird

这个类库除了兼容 Promise 规范之外,还扩展了 取消promise 对象的运行,取得 promise 的运行进度,以及 错误处理的扩展检测 等非常丰富的功能。

3.2 使用 reject 还是 throw error

Promise的构造函数,以及then调用的函数都可以认为是在try catch代码块中执行的,所以这些代码内部使用throw,程序不会因为异常而终止。

promise 中使用 throw,会被try catch住,最终 promise 变为 rejected 状态。

3.3 在then中使用reject

3.4 处理超时

3.4.1 超时取消xhr请求

3.5 Promise#done

这种被内部消化的问题叫做 unhandled rejection,即rejected时没有找到响应的处理程序。 promise.prototype.done的源码

使用起来和 .then 一样,但是不会返回一个 promise 值,因此不能链式调用,即只能出现在方法链的最后面。因此:

3.6 More

4.7,4.8 两节应该多看!关于用Promise包装API以及顺序处理Promise的问题

4. 参考资料

Last updated

Was this helpful?