第四章 Promise 的 API
1 构造函数 Promise
用法:
new Promise( function(resolve, reject) {...} /* executor函数(执行器函数) */ );
参数:
executor 函数
executor 是带有
resolve
和reject
两个参数的函数 。Promise 构造函数执行时立即调用executor
函数,resolve
和reject
两个函数作为参数传递给executor
。
说明:
- executor 函数会在 Promise 内部立即同步调用。
- executor 内部通常会执行一些异步操作,一旦异步操作执行完毕(可能成功/失败),要么调用resolve函数来将promise 状态改成 fulfilled ,要么调用
reject
函数将promise的状态改为rejected。 - 如果在executor函数中抛出一个错误,那么该promise 状态为rejected。executor函数的返回值被忽略。
2 Promise.prototype.then()
说明:
为 Promise 对象添加状态改变时的回调函数。
用法:
p.then(onResolved[, onRejected]);
参数:
onResolved
可选当 Promise 变成成功状态(resolved)时调用的函数。该函数有一个参数,即接受的最终结果(the fulfillment value)。如果该参数不是函数,则会在内部被替换为
(x) => x
,即原样返回 promise 最终结果的函数。onRejected
可选当 Promise 变成成功状态或失败状态(rejected)时调用的函数。该函数有一个参数,即失败的原因(
rejection reason
)。 如果该参数不是函数,则会在内部被替换为一个 "Thrower" 函数 (it throws an error it received as argument)。
返回值:
当一个 Promise 完成或者失败时,返回函数将被异步调用(由当前的线程循环来调度完成)。具体的返回值依据以下规则返回。如果 then
中的回调函数:
- 返回了一个值,那么
then
返回的 Promise 将会成为成功状态,并且将返回的值作为成功状态的回调函数的参数值。 - 没有返回任何值,那么
then
返回的 Promise 将会成为成功状态,并且该成功状态的回调函数的参数值为undefined
。 - 抛出一个错误,那么
then
返回的 Promise 将会成为失败状态,并且将抛出的错误作为失败状态的回调函数的参数值。 - 如果返回的是另一个 Promise 实例, 那么
then
返回的 Promise 的状态和值斗鱼这个 Promise 实例保持一致。
3 Promise.protype.catch()
说明:
Promise.prototype.catch()
方法是.then(null, rejection)
或.then(undefined, rejection)
的别名,用于指定发生错误时的回调函数。
用法:
p.catch(onRejected);
参数
onRejected
当Promise 被 rejected 时,被调用的一个函数。 该函数拥有一个参数:
reason
rejection 的原因。如果
onRejected
抛出一个错误或返回一个本身失败的 Promise , 通过catch()
返回的Promise 被rejected;否则,它将显示为成功(resolved)。
返回值:
catch()
返回一个 Promise 对象,规则同 then()
方法相同。
catch()
方法是 then()
方法的语法糖, 相当于: then(undefined, onRejected)
。
4 Promise.prototype.finally()
说明:
finally()
方法用于指定不管 Promise 对象最后状态如何,都会执行的操作。该方法是 ES2018 引入标准的。
这为在Promise
是否成功完成后都需要执行的代码提供了一种方式。这避免了同样的语句需要在then()
和catch()
中各写一次的情况。
用法:
p.finally(onFinally);
参数
onFinally
Promise
结束后调用的函数。该回调函数不接受任何参数,这意味着没有办法知道,前面的 Promise 状态到底是resolved
还是rejected
。这表明,finally
方法里面的操作,应该是与状态无关的,不依赖于 Promise 的执行结果。
返回值:
finally()
方法返回一个 Promise 对象。与 then()
和 catch()
不同的是,finally()
总是返回原来的值。
注意: 在
finally
回调中抛出错误或者返回 rejected 状态的 Promise 对象,将得到指定原因(抛出的错误或者 Promise 对象的 reason)的新的 rejected 状态的 Promise对象。
5 Promise.resolve()
说明:
有时需要将现有对象转为 Promise 对象,Promise.resolve()
方法就起到这个作用。
用法:
Promise.resolve(value);
参数:
Promise.resolve()
方法的参数分成四种情况:
1)参数是一个 Promise 实例
如果参数是 Promise 实例,那么
Promise.resolve
将不做任何修改、原封不动地返回这个实例。2)参数是一个 thenable 对象
thenable
对象指的是具有then
方法的对象,比如下面这个对象。let thenable = { then: function(resolve, reject) { resolve(1024); } };
Promise.resolve
方法会将这个对象转为 Promise 对象,然后就立即执行thenable
对象的then
方法。let thenable = { then: function(resolve, reject) { resolve(42); } }; let p1 = Promise.resolve(thenable); p1.then(function(value) { console.log(value); // 42 });
3)参数是一个原始值,或者是一个不具有
then
方法的对象返还一个状态是 resolved 的 Promise 实例,
Promise.resolve()
的参数作为传入的值。4)不带任何参数
直接返回一个
resolved
状态的 Promise 对象,传入的值是 undefined
返回值:
返回一个带着给定值的Promise
对象,如果参数本身就是一个Promise
对象,则直接返回这个Promise
对象。
6 Promise.reject()
说明:
Promise.reject(reason)
方法会返回一个新的 Promise 实例,该实例的状态为rejected
。
用法:
Promise.reject(reason);
参数:
reason
表示
Promise
被失败的原因。注意,
Promise.reject()
方法的参数,会原封不动地作为reject
的理由,变成后续方法的参数。这一点与Promise.resolve
方法不一致。
返回值:
一个给定原因了的已失败的 Promise 实例。
7 Promise.all()
说明:
Promise.all()
方法用于将多个 Promise 实例,包装成一个新的 Promise 实例。
用法:
Promise.all([p1, p2, p3]);
参数:
Promise.all()
方法接受一个数组作为参数,p1
、p2
、p3
都是 Promise 实例,如果不是,就会先调用前面讲到的Promise.resolve
方法,将参数转为 Promise 实例,再进一步处理。另外,Promise.all()
方法的参数可以不是数组,但必须具有 Iterator 接口,且返回的每个成员都是 Promise 实例。
返回值:
返回一个 Promsie 实例。Promise实例的状态由p1
、p2
、p3
决定,分成两种情况:
- 1)只有
p1
、p2
、p3
的状态都变成resolved
,p
的状态才会变成resolved
,此时p1
、p2
、p3
的返回值组成一个数组,传递给的回调函数。 - 2)只要
p1
、p2
、p3
之中有一个被rejected
,p
的状态就变成rejected
,此时第一个被reject
的实例的返回值,会传递给回调函数。
注意: 如果
Promise.all()
的参数不具有 Iterator 接口,返回一个状态是 rejected 的 Promise 实例,错误信息错误失败的原因。
8 Promise.race()
说明:
Promise.race()
方法同样是将多个 Promise 实例,包装成一个新的 Promise 实例。
一旦迭代器中的某个 Promise 实例状态率先变为 resolved 或 rejected,返回的 Promise 实例就会跟着变,那个率先改变的 Promise 实例的返回值,就传递给回调函数。
用法:
Promise.race([p1, p2, p3]);
参数:
Promise.race()
方法的参数与Promise.all()
方法一致,接受一个数组或者 Iterator 作为参数,要求每个成员都是 Promise 实例。
返回值:
一个 Promise 实例,状态由参数中率先改变状态的 Promise 实例决定。
9 Promise.allSettled()
说明:
Promise.allSettled()
同样是将多个 Promise 实例包装成一个新的 Promise 实例。
不同的是,只有等到所有这些参数实例都返回结果,不管是每个 Promise 实例是resolved
还是rejected
,包装实例才会结束。该方法由 ES2020 引入。
用法:
Promise.allSettled([p1, p2, p3]);
参数:
与 Promise.race()
方法和Promise.all()
方法的参数一致。
返回值:
返回值是个 Promise 实例,状态只可能变成 resolved。
监听函数接收到的参数是数组,该数组的每个成员都是一个对象,对应传入Promise.allSettled()
的几个 Promise 实例。每个对象都有status
属性,该属性的值只可能是字符串fulfilled
(resolved 状态)或字符串rejected
。fulfilled
时,对象有value
属性,rejected
时有reason
属性,对应两种状态的返回值。
[
{
"status":"fulfilled",
"value":"哈哈哈哈哈"
},
{
"status":"rejected",
"reason":"嘤嘤嘤"
}
]