一:Promise 基本方法---注意点
1. Promise.all()
-------如果作为参数的 Promise 实例,自己定义了catch方法,那么它一旦被rejected,并不会触发Promise.all()的catch方法;
-------Promise.all()方法的参数可以不是数组,但必须具有 Iterator 接口,且返回的每个成员都是 Promise 实例,即由promise 实例组成的数组或者其他具有 Iterator 接口的数据结构。当所有参数promise状态都是成功时,所有参数promise返回值组成一 个数组,传递给该方法后面跟的then/catch等回调函数。 之中有一个参数被rejected,方法的状态就变成rejected,此时第 一个被reject的实例的返回值,会传递给回调函数;
-------Promise.all()可以确定所有请求都成功了,但是只要有一个请求失败,它就会报错,而不管另外的请求是否结束。
2. Promise.race()
-------Promise.race()方法同样是将多个 Promise 实例,包装成一个新的 Promise 实例
const p = Promise.race([p1, p2, p3]);
-------上面例子中有一个实例率先改变状态,p的状态就跟着改变。那个率先改变的 Promise 实例的返回值,就传递给p的回调函数。
3. Promise.allSettled()
-------ES2020 引入了Promise.allSettled()方法,用来确定一组异步操作是否都结束了(不管成功或失败),弥补all方法的不足
-------该方法返回的新的 Promise 实例,一旦发生状态变更,状态总是fulfilled,不会变成rejected。状态变成fulfilled后, 它的回调函数会接收到一个数组作为参数,该数组的每个成员对应前面数组的每个 Promise 对象
const resolved = Promise.resolve(42);
const rejected = Promise.reject(-1);
const allSettledPromise = Promise.allSettled([resolved, rejected]);
allSettledPromise.then(function (results) {
console.log(results);
});
// [
// { status: 'fulfilled', value: 42 },
// { status: 'rejected', reason: -1 }
// ]
4. Promise.any()
-------ES2021 引入了Promise.any()方法。该方法接受一组 Promise 实例作为参数,包装成一个新的 Promise 实例返回。
-------只要参数实例有一个变成fulfilled状态,包装实例就会变成fulfilled状态;如果所有参数实例都变成rejected 状态,包装实例就会变成rejected状态。且方法后面如果跟catch函数则会导出错误,错误是所有实例错误组成的数组。
5. Promise.resolve()
-------用处:将现有对象转为 Promise 对象;
-------Promise.resolve("foo") === new Promise(resolve => resolve('foo'))
-------Promise.resolve()方法允许调用时不带参数,直接返回一个resolved状态的 Promise 对象; 如果希望得到一个 Promise 对象,比较方便的方法就是直接调用Promise.resolve()方法。
//相关的事件循环机制示例:
setTimeout(function () {
console.log('three');
}, 0); //setTimeout(fn, 0)在下一轮“事件循环”开始时执行
Promise.resolve().then(function () {
console.log('two');
}); //立即resolve()的Promise对象,是在本轮“事件循环”(event loop)的结束时执行,而不是在下一轮“事件循环”的开始时。
console.log('one');
// one
// two
// three
6. Promise.reject()
-------Promise.reject(reason)方法也会返回一个新的 Promise 实例,该实例的状态为rejected;
-------Promise.reject()方法的参数,会原封不动地作为reject的理由,变成后续方法的参数。
7. Promise.try()
-------实际开发中,经常遇到一种情况:不知道或者不想区分,函数f是同步函数还是异步操作, 但是想用 Promise 来处理它。因为这样就可以不管f是否包含异步操作,都用then方法指定 下一步流程,用catch方法处理f抛出的错误。
-------让同步函数同步执行,异步函数异步执行,并且让它们具有统一的 API;
-------所以如果想用then方法管理流程,最好都用Promise.try包装一下。这样有许多好处, 其中一点就是可以更好地管理异常。