ECMAScript 6 笔记(19)- Promise (2)

原创 乘风逐月 随笔 ES6 63阅读 2018-11-13 16:18:17 举报

一、Promise对象方法

1. Promise.resolve()

Promise.resolve 方法的作用是:有需要时将现有对象转为 Promise 对象。

上面的代码将 jQuery 生成的 deferred 对象,转为一个新的 Promise 对象

Promise.resolve 方法的参数分成四种情况:

(1)参数是一个 Promise 实例
如果参数是 Promise 实例,那么 Promise.resolve 将不做任何修改、原封不动的返回这个实例。
(2)参数是一个 thenable 对象
thenable 对象指的是具有 then 方法的对象,例如:

Promise.resolve 方法会将这个对象转为 Promise 对象,然后就立即执行 thenable 对象的 then 方法。

上例中,thenable 对象的 then 方法执行后,对象 p1 的状态就变为 resolved,从而立即执行最后那个 then 方法指定的回调函数,输出 42。
(3)参数不是具有 then 方法的对象,或根本就是对象
如果参数是一个原始值,或者是一个不具有 then 方法的对象,则 Promise.resolve 方法返回一个新的 Promise 对象,状态为 resolved。

上面代码生成一个新的 Promise 实例 p。由于字符串 hello 不属于异步操作(判断方法是字符串对象不具有 then 方法),返回 Promise 实例的状态从一生成就是 resolved,所以回调函数会立即执行。Promise.resolve 方法的参数,会同时传给回调函数。
(4)不带有任何参数
Promise.resolve 方法允许调用时不带参数,直接返回一个 resolveed 状态的 Promise 对象。
所以想要一个 Promise 对象,可以直接调用 Promise.resolve 方法。例如:

注意:
立即 resolve 的 Promise 对象,是在本轮 “事件循环” 的结束时,而不是在下一轮 “事件循环” 的开始时。

上例中,setTimeout(fn,0)在下一轮 “事件循环” 开始时执行,Promise.resolve() 在本轮 “事件循环” 结束时执行,console.log('33') 则是立即执行,因此最先输出。

2. Promise.all()

Promise.all 方法用于将多个 Promise 实例,包装成一个新的 Promise 实例。

上例中,Promise.all 方法接受一个数组作为参数,p1,p2,p3 都是 Promise 实例,如果不是,就会先调用 Promise.resolve 方法,将参数转为 Promise 实例再进一步处理。
Promise.all 方法的参数可以不是数组,但必须有 Iterator 接口,且返回的每个成员都是 Promise 实例。
p 的状态由 p1,p2,p3决定,分成两种情况:
(1)只有 p1,p2,p3 的状态都变成 fulfilled,p 的状态才会变成 fulfilled,此时 p1,p2,p3 的返回值组成一个数组,传递给 p 的回调函数。
(2)只要 p1,p2,p3 之中有一个被 rejected,p 的状态就变成 rejected,此时第一个被 reject 的实例的返回值,会传递给 p 的回调函数。
注意:
如果作为参数的 Promise 实例,自己定义了 catch 方法,那么它一旦被 rejected,并不会触发 Promise.all() 的 catch 方法。

上例中,p1 会 resolved,p2 首先会 rejected,但是 p2 有自己的 catch 方法,该方法返回一个新的 Promise 实例,p2 指向的实际上是这个实例。该实例执行完 catch 方法后,也会变成 resolved,导致 Promise.all() 方法参数里面的两个实例都会 resolved,因此会调用 then 方法指定的回调函数,而不会调用 catch 方法指定的回调函数。

如果 p2 没有自己的 catch 方法,就会调用 Promise.all() 的 catch 方法。

3. Promise.race()

Promise.race() 方法同样是将多个 Promise 实例,包装成一个新的 Promise 实例。

上例中,只要p1,p2,p3之中有一个实例率先改变状态,p 的状态就跟着改变。那个率先改变的 Promise 实例的返回值,就传递给 p 的回调函数。
Promise.race 方法的参数与 Promise.all 方法一样,如果不是 Promise 实例,就会先调用 Promise.resolve 方法,将参数转为 Promise 实例,再进一步处理。
下例中,如果指定事件内没有获得结果,就将 Promise 的状态变为 reject,否则变为 resolve。

上例中,如果 5 秒内无法返回结果,变量 p 的状态就会变为 rejected,从而触发 catch 方法指定的回调函数。

4. Promise.reject()

Promise.reject(reason) 方法也会返回一个新的 Promise 实例,该实例的状态为 rejected。

上例中,生成一个 Promise 实例 p,状态为 rejected,回调函数会立即执行。
注意:
Promise.reject() 方法的参数,会原封不动的作为 reject 的理由,变成后续方法的参数,这一点与 Promise.resolve 方法不一致。

上例中,Promise.reject 方法的参数是 thenable 对象,执行后,后面 catch 方法的参数不是 reject 抛出的 ‘出错了’ 的字符串,而是 thenable 对象。

评论 ( 0 )
最新评论
暂无评论

赶紧努力消灭 0 回复