ES6 Promise
本文最后更新于 2024年6月7日 下午
Promise
基本用法
-
对象的状态不受外界影响,只有内部执行才能决定
Promise的状态。 -
一旦状态改变,就不会再变,任何时候都可以得到这个结果,如果改变已经发生了,你再对
Promise对象添加回调函数,也会立即得到这个结果。 -
可以对
Promise添加多个回调函数。 -
Promise一旦新建就会立即执行,无法中途取消。 -
Promise内部抛出的错误不会反应到外部。
Promise构造函数接受一个函数作为参数,该函数的两个参数分别是resolve和reject。它们是两个函数,由 JavaScript 引擎提供,不用自己部署。
then
.then 的第一个参数是一个函数,该函数将在 promise resolved 后运行并接收结果。
.then 的第二个参数也是一个函数,该函数将在 promise rejected 后运行并接收 error。
1 | |
catch
-
Promise.prototype.catch()方法是.then(null, rejection)或.then(undefined, rejection)的别名,用于指定发生错误时的回调函数。 -
如果
Promise状态已经变成resolved,再抛出错误是无效的。因为Promise的状态一旦改变,就永久保持该状态,不会再变了。 -
Promise对象的错误具有“冒泡”性质,会一直向后传递,直到被捕获为止。1
promise.then().then().catch(); -
Promise中发生的错误,不会影响外界。1
2
3
4
5
6
7
8
9
10
11
12
13
14const someAsyncThing = function() {
return new Promise(function(resolve, reject) {
// 下面一行会报错,因为x没有声明
resolve(x + 2);
});
};
someAsyncThing().then(function() {
console.log('everything is great');
});
setTimeout(() => { console.log(123) }, 2000);
// Uncaught (in promise) ReferenceError: x is not defined
// 123
finally
finally()方法用于指定不管 Promise 对象最后状态如何,都会执行的操作。是then()的特例。
all
Promise.all()方法用于将多个 Promise 实例,包装成一个新的 Promise 实例。
上面代码中,Promise.all()方法接受一个数组作为参数,另外,Promise.all()方法的参数可以不是数组,但必须具有 Iterator 接口,且返回的每个成员都是 Promise 实例。
如果成员不是Promise实例,就会先调用下面讲到的Promise.resolve方法,将参数转为 Promise 实例,再进一步处理。
例如:
1 | |
-
只有
p1、p2、p3的状态都变成fulfilled,p的状态才会变成fulfilled,此时p1、p2、p3的返回值组成一个数组,传递给p的回调函数。 -
只要
p1、p2、p3之中有一个被rejected,p的状态就变成rejected,此时第一个被reject的实例的返回值,会传递给p的回调函数。
可以理解为“与”操作。
any
该方法接受一组 Promise 实例作为参数,包装成一个新的 Promise 实例返回。只要参数实例有一个变成fulfilled状态,包装实例就会变成fulfilled状态;如果所有参数实例都变成rejected状态,包装实例就会变成rejected状态。
可以理解为”或“操作。
race
方法的具体功能如方法名一样。
只要p1、p2、p3之中有一个实例率先改变状态,p的状态就跟着改变。那个率先改变的 Promise 实例的返回值,就传递给p的回调函数。
allSettled
Promise.allSettled()方法接受一组 Promise 实例作为参数,包装成一个新的 Promise 实例。只有等到所有这些参数实例都返回结果。
1 | |
resolve
Promise.resolve()方法将现有对象转为 Promise 对象。
-
参数是一个
Promise实例:如果参数是
Promise实例,那么Promise.resolve将不做任何修改、原封不动地返回这个实例。 -
参数是一个
thenable对象:thenable对象指的是具有then方法的对象。Promise.resolve()方法会将这个对象转为 Promise 对象,然后就立即执行thenable对象的then()方法。 -
参数不是具有
then()方法的对象,或根本就不是对象:如果参数是一个原始值,或者是一个不具有
then()方法的对象,则Promise.resolve()方法返回一个新的Promise对象,状态为resolved。1
2
3
4
5
6const p = Promise.resolve('Hello');
p.then(function (s) {
console.log(s)
});
// Hello -
不带有任何参数:
Promise.resolve()方法允许调用时不带参数,直接返回一个resolved状态的Promise对象。但是需要注意:这个对象的then方法在本轮事件循环结束时执行。
reject
上面代码生成一个 Promise 对象的实例,状态为rejected,回调函数会立即执行。
try
由于catch只能捕获Promise对象内部的异步错误,要想捕获同步错误,需要写成这样:
1 | |
但是可以用Promise.try改写上述:
1 | |