1. 一般总是建议,Promise 对象后面要跟catch
方法,这样可以处理 Promise 内部发生的错误。
catch
方法返回的还是一个 Promise 对象,因此后面还可以接着调用then
方法。
const p1 =new Promise((resolve, reject) => { resolve(x+2); // 会报错,因为x没有声明 }); p1.catch((err) => { console.log('oh no', err); // catch 返回一个resolved promise对象 }).then(() => { console.log('carry on'); }); // oh no ReferenceError: x is not defined // carry on
catch方法中,还能再抛出错误。
const someAsyncThing = function() { return new Promise(function(resolve, reject) { // 下面一行会报错,因为x没有声明 resolve(x + 2); }); }; someAsyncThing().then(function() { return someOtherAsyncThing(); }).catch(function(error) { console.log('oh no', error); // 下面一行会报错,因为 y 没有声明 y + 2; }).then(function() { console.log('carry on'); //没有执行,因为catch中返回的是一个reject的promise }); // oh no [ReferenceError: x is not defined]
catch
方法抛出一个错误,因为后面没有别的catch
方法了,导致这个错误不会被捕获,也不会传递到外层。
2. promise.all与promise.race
a. promise.all与promise.race的参数如果不是 Promise 实例,就会先调用Promise.resolve
方法,将参数转为 Promise 实例,再进一步处理。
const p = Promise.race([p1, p2, p3]);
只要p1
、p2
、p3
之中有一个实例率先改变状态,p
的状态就跟着改变。
b. 如果作为参数的 Promise 实例,自己定义了catch
方法,那么它一旦被rejected
,并不会触发Promise.all()
的catch
方法。
let p3 = new Promise((resolve, reject) => { resolve('hello'); }) .then(result => result) .catch(e => e); let p4 = new Promise((resolve, reject) => { throw new Error('报错了'); }) .then(result => result) .catch(e => e); // catch 返回一个resolved promise对象
Promise.all([p3, p4])
.then(result => console.log('hi', result))
.catch(e => console.log(e));
// hi ["hello", Error: 报错了] //执行的是then方法,而非catch方法
p1
会resolved
,p2
首先会rejected
,但是p2
有自己的catch
方法,该实例执行完catch
方法后,也会变成resolved
,导致Promise.all()
方法参数里面的两个实例都会resolved
,因此会调用then
方法指定的回调函数,而不会调用catch
方法指定的回调函数。
3.链式写法
let p2 = new Promise((resolve, reject) => { if(hi === "hi"){ reject(5); } }); p2.then(() => { console.log(1); }) .catch(() => {console.log(2);}) .then(() => {console.log(3);}) .catch(() => {console.log(4);});
// 2
// 3
4. 中间值
场景: 我们先调起promise1,然后根据返回值,调用promise2,之后再根据这两个Promises的值,调取promise3。
promise实现:
const makeRequest = () => { return promise1() .then(value1 => { // do something return promise2(value1) .then(value2 => { // do something return promise3(value1, value2) }) }) }
同样的场景,使用async/await会非常简单:
const makeRequest = async () => { const value1 = await promise1(); const value2 = await promise2(value1); return promise3(value1, value2); }