前言
阅读本文前请先了解宏任务与微任务、EventLoop机制\color{#33CC99}{宏任务与微任务、EventLoop机制}宏任务与微任务、EventLoop机制等基本概念
API
Promise.prototype.then()
返回的是一个promise,可以链式调用
- then方法中返回值或者没返回值时,返回promise为resolved状态
new Promise((resolve, reject) => {
resolve(1);
}).then(data => {
console.log(data);
return 2;
}).then(data => {
console.log(data)
}).then(data => {
console.log(data)
})
// 输出 1 2 undefined
- 返回一个rejected或resolved的promise,返回promise为前者状态
new Promise((resolve, reject) => {
resolve(1);
}).then(data => {
console.log(data);
return Promise.resolve(2);
}).catch(err => {
console.log(err)
}).then(data => {
console.log(data)
throw("3")
}).catch(err => {
console.log(err)
})
// 输出1 2 3
- 在then方法中,若只是执行resolve()或者reject(),并没有返回的话,后续的then/catch执行函数入参为undefined
new Promise((resolve, reject) => {
resolve(1);
}).then(data => {
console.log(1);
Promise.resolve(2);
}).catch(err => { console.log(err)
}).then(data => {
console.log(data)
throw("3")
}).catch(err => {
console.log(err)
})
// 输出1 undefined 3
// Promise.resolve(2)这里并未return
- then()里执行异步任务
new Promise((resolve, reject) => {
resolve(1)
}).then(data => {
setTimeout(() => {
console.log(data)
Promise.resolve(2);
}, 1000);
}).then(data => {
console.log(data);
})
// 输出 undefined 1
// setTimeout为宏观任务,且第一个then并未返回promise
- then()里执行异步任务,但希望后续的then()同步执行
new Promise((resolve, reject) => {
resolve(1)
}).then(data => {
return new Promise((resolve,reject) => {
setTimeout(() => {
console.log(data)
resolve(2);
}, 500)
})
}).then(data => {
console.log(data);
})
// 输出 1 2
Promise.prototype.catch()
catch方法返回一个Promise,若catch方法抛出错误或返回一个rejected的Promise,该返回Promise状态为rejected;否则,该返回Promise状态为resolved
- 在异步函数中抛出的错误不会被catch捕获到;但reject会被捕获到
new Promise((resolve, reject) => {
setTimeout(() => {
throw "p Error";
}, 1000);
}).catch((e) => {
console.log(e);
});
// 抛出异常 Uncaught p Error
new Promise((resolve, reject) => {
setTimeout(function() {
reject("p Error");
}, 1000);
}).catch((e) => {
console.log(e);
});
// 输出 p Error
- 在resolve()后面抛出的错误会被忽略
new Promise((resolve, reject) => {
resolve();
throw "p1 Error";
}).catch((e) => {
console.log(e);
});
// 无输出
- catch捕获后,若catch方法抛出错误或返回Promise.reject(),该返回Promise状态为rejected
new Promise((resolve, reject) => {
reject(1);
}).catch(e => {
console.log(e);
return Promise.reject(2);
}).then(() => {
console.log(3);
}).catch(e => {
console.log(e)
})
// 输出 1 2
// 第一个catch捕获到异常,输出1,然后返回了rejected的promise
// 第二个catch捕获到上述的promise,输出2
复制代码
new Promise((resolve, reject) => {
reject(1);
}).catch(e => {
console.log(e);
Promise.reject(2);
}).then(() => {
console.log(3);
}).catch(e => {
console.log(e)
})
// UnhandledPromiseRejectionWarning
// 因为第一个catch未返回失败的promise,而是直接执行了,导致第二个catch捕获失败,抛出异常
Promise.prototype.finally()
返回一个promise,注意执行时机是在前面的promise状态确定后,其他特性与then、catch一致
Promise.all(iterable)
当iterable均resolved后,Promise.all状态变为resolved;若其中有一个rejected,Promise.all状态立刻变为rejected
- iterable可以为空数组或空字符串,此时相当于Promise已经resolved;若为空,会抛出Promise异常
Promise.all([]).then(res=>{
console.log(res)
})
// 输出[]
Promise.all("").then(res=>{
console.log(res)
})
// 输出[]
Promise.all().then(res=>{
console.log(res)
})
// Promise报错
// Uncaught (in promise) TypeError: undefined is not iterable (cannot read property Symbol(Symbol.iterator))
at Function.all (<anonymous>)
at <anonymous>:1:
- iterable若非Promise,相当于Promise已经resolved
let promise1 = new Promise((resolve,reject)=>{
resolve(1)
})
let promise2 = new Promise((resolve,reject)=>{
resolve(2)
})
Promise.all([promise1,promise2,3]).then(res=>{
console.log(res)
})
// 输出[1,2,3]
Promise.race(iterable)
Promise.race状态与iterable中第一个返回的状态相同
let promise = new Promise((resolve,reject)=>{
reject(1)
})
Promise.race([promise,2]).then(res=>{
console.log(res)
}).catch(err => {console.log(err)})
// 输出1
- 注意与下例的区别,顺序不同导致输出不同,体会一下
let promise = new Promise((resolve,reject)=>{
reject(1)
})
Promise.race([2,promise]).then(res=>{
console.log(res)
}).catch(err => {console.log(err)})
// 输出2
- 当使用定时器,resolve()变成了宏任务,输出又不同了
let promise = new Promise((resolve,reject)=>{
setTimeout(function() {resolve(1)}, 1000);
})
Promise.race([promise,2]).then(res=>{
console.log(res)
})
// 输出2
所以,要深刻体会 第一个 的意思
- iterable为空数组或空字符串,会一直等待,这点与Promise.all不一样;若为空,会抛出Promise异常
Promise.race([]).then(res=>{
console.log(res)
}).catch(e => {console.log(e)})
// 什么都不输出
Promise.allSettled(iterable)
当iterable数组均执行完成(resolve或reject),Promise.all状态变为resolved,其入参是iterable的每个promise结果,包含status字段表明该iterable的执行结果
- iterable均执行结束后,allSettled状态变为resolve
const promise1 = Promise.resolve(3);
const promise2 = Promise.reject(2);
Promise.allSettled([promise1, promise2])
.then((results) => results.forEach((result) => console.log(result.status)));
// 输出
// fulfilled
// rejected
- iterable若非Promise,相当于Promise已经resolved
- iterable为空数组或空字符串,会一直等待,这点与Promise.all不一样;若为空,会抛出Promise异常
Promise.any(iterable)
iterable中第一个resolved后,Promise.any变为resolved;若iterable数组都rejected了,Promise.any变为rejected 该API尚未被所有浏览器支持!!!处于Stage4状态!!!不建议使用!!!
- 和race不一样,race等待第一个完成的promise,any等待第一个成功的promise;其他与race一致