Promise
-
const promise = new Promise(function(resolve, reject) { //Promise构造函数接受一个函数作为参数,该函数接收两个参数 //这两个参数由JS引擎提供,无需自己部署 if(/* 异步操作成功 */) { resolve(value); } else { reject(error); } })
-
resolve
:-
将
Promise
对象状态由pending
变为fulfilled
-
将异步操作的结果作为参数传出
-
resolve
函数的参数还可能是一个promise
实例const p1 = new Promise((resolve, reject) => { setTimeout(() => { console.log(new Date()); reject(new Error("p1 failed!!")); }, 2000); }); const p2 = new Promise((resolve, reject) => { setTimeout(() => resolve(p1), 4000); });
此时,
p1
的状态决定着p2
的状态
-
-
reject
:- 将
Promise
对象状态由pending
变为rejected
- 将异步操作的报错作为参数传出
- 将
then
方法//then方法接受两个回调函数作为参数 promise.then(function(value) { //第一个回调函数在对象状态变为resolved时调用 }, function(error) { //第二个回调函数在对象状态变为rejected时调用 //可选参数 })
两个函数接收的参数均为
Promise
对象传出的值其中,第二个函数是可选的
Promise.prototype.then()
then
方法:为Promise
实例添加状态改变时的回调函数then
方法返回的是一个新的Promise
实例(不是原来的实例),因此可以采用链式写法Promise.prototype.catch()
-
该方法是
.then(null, reject)
或then(undefined, reject)
的别名,用于指定发生错误时的回调函数 -
无论是异步操作发生的错误还是
then
方法指定的回调函数抛出的错误,都会被catch
方法捕获 -
如果没有使用
catch
方法指定错误处理的回调函数,Promise
对象抛出的错误不会传递到外层代码,也就是Promise
会“吃掉错误” -
Node
有一个unhandelRejection
事件,专门监听未捕获的reject
错误 -
const promise = new Promise(function (resolve, reject) { resolve('ok'); setTimeout(function () { throw new Error('test') }, 0) }); promise.then(function (value) { console.log(value) });
上述代码再
Promise
运行结束后抛出了一个错误,即是在Promise
函数体外抛出的,因此会冒泡到最外层被捕获 -
catch
方法返回的也是一个promise
对象
Promise.prototype.finally()
不管
promise
最后的状态是什么,在执行完then
或者是catch
回调函数以后,都会执行finally
方法指定的回调函数<!--测了一下,好像在promise状态凝固了以后finally就直接执行了,-->
finally
方法的回调函数不接受任何参数,这意味着没有办法知道,前面的 Promise 状态到底是fulfilled
还是rejected
。这表明,finally
方法里面的操作,应该是与状态无关的,不依赖于 Promise 的执行结果。finally
本质上是then
方法的特例。Promise.protoype.all()
用于将多个
Promise
实例包装成一个新的Promise
实例const p = Promise.all([p1, p2, p3]);
-
参数:
- 有
Iterator
接口 - 返回的每个成员都是
Promise
实例
- 有
-
新实例的状态
- 当所有成员的状态变成
fulfilled
,新实例的状态也会变成fulfilled
,此时将所有成员的返回值组成一个数组传给新实例的回调函数 - 当有一个成员的状态为
rejected
,新实例的状态就变成rejected
,第一个被reject
的实例的返回值会被传给新实例的回调函数
- 当所有成员的状态变成
-
关于
catch
如果作为参数的 Promise 实例,自己定义了
catch
方法,那么它一旦被rejected
,并不会触发Promise.all()
的catch
方法。const p1 = new Promise((resolve, reject) => { resolve('hello'); }) .then(result => result) .catch(e => e); const p2 = new Promise((resolve, reject) => { throw new Error('报错了'); }) .then(result => result) .catch(e => e); Promise.all([p1, p2]) .then(result => console.log(result)) .catch(e => console.log(e)); // ["hello", Error: 报错了]
上面代码中,
p1
会resolved
,p2
首先会rejected
,但是p2
有自己的catch
方法,该方法返回的是一个新的 Promise 实例,p2
指向的实际上是这个实例。该实例执行完catch
方法后,也会变成resolved
,导致Promise.all()
方法参数里面的两个实例都会resolved
,因此会调用then
方法指定的回调函数,而不会调用catch
方法指定的回调函数。如果
p2
没有自己的catch
方法,就会调用Promise.all()
的catch
方法。
Promise.race()
用于将多个
Promise
实例包装成一个新的Promise
实例与
all()
不同的是,只要有一个实例的状态改变了,新实例的状态就会随之改变接收参数:第一个改变的实例的返回值会被传给
p
的回调函数Promise.allSettled()
用于将多个
promise
实例包装成一个新的Promise
实例当所有的参数实例都返回结果后(无论成功还是失败),新实例才会结束
新实例一旦结束,状态只会是
fulfilled
,不会变成rejected
接收参数:
Promise.any()
用于将多个
promise
实例包装成一个新的Promise
实例只要参数实例有一个变成
fulfilled
状态,包装实例就会变成fulfilled
状态;如果所有参数实例都变成rejected
状态,包装实例就会变成rejected
状态。Promise.resolve()
用于将对象转为
Promise
对象-
Promise
实例调用该函数将原封不动地返回实例
-
thenable
对象一个具有
then
方法的对象- 将对象转成
Promise
对象 - 立刻执行该对象的
then
方法
- 将对象转成
-
不具有
then
方法的对象/不是对象- 返回一个新的
Promise
对象 - 新对象状态为
resolved
- 参数传给回调函数
- 返回一个新的
-
无参数
- 直接返回一个状态为
resolved
的Promise
对象
- 直接返回一个状态为
Promise.reject()
Promise.reject(reason)
方法也会返回一个新的 Promise 实例,该实例的状态为rejected
。const p = Promise.reject('出错了'); // 等同于 const p = new Promise((resolve, reject) => reject('出错了')) p.then(null, function (s) { console.log(s) }); // 出错了
上面代码生成一个 Promise 对象的实例
p
,状态为rejected
,回调函数会立即执行。注意,
Promise.reject()
方法的参数,会原封不动地作为reject
的理由,变成后续方法的参数。这一点与Promise.resolve
方法不一致。
-