Promise详解
Promise
解决回调地狱问题
当我们new一个promise,此时我们需要传递一个回调函数,这个函数为立即执行的,称之为(executor)
这个回调函数,我们需要传入两个参数回调函数,reslove,reject(函数可以进行传参)
- 当执行了
reslove函数,会回调promise对象的.then函数 - 当执行了
reject函数,会回调promise对象的.catche函数
Executor立即执行
1 | |

Promise状态
使用promise的时候,给它一个承诺,我们可以将他划分为三个阶段
- pending(待定),执行了executor,状态还在等待中,没有被兑现,也没有被拒绝
- fulfilled(已兑现),执行了
resolve函数则代表了已兑现状态 - rejected(已拒绝),执行了
reject函数则代表了已拒绝状态
首先,状态只要从待定状态,变为其他状态,则状态不能再改变
1 | |
- 当我调用
reject之后,在调用resolve是无效的,因为状态已经发生改变,并且是不可逆的。
resolve不同值的区别
如果
resolve传入一个普通的值或者对象,只能传递接受一个参数,那么这个值会作为then回调的参数1
2
3
4
5
6new Promise((resolve, reject) => {
resolve({name: '张三', age: 5})
}).then(res => {
console.log(res);
})
// {name: '张三', age: 5}如果
resolve中传入的是另外一个Promise,那么这个新Promise会决定原Promise的状态1
2
3
4
5
6
7
8
9
10
11
12const promise = new Promise((resolve, reject) => {
resolve(new Promise((resolve, reject) => {
setTimeout(() => {
reject('执行失败')
}, 3000);
}))
})
promise.then(res => console.log(res))
.catch(err => console.log(err))
// 打印内容: 执行失败上述例子虽然执行的是resolve,但是会触发传入的Promise的reject,从而执行catch方法。所以新传入的Promise会决定原来的Promise状态;
如果
resolve中传入的是一个对象,并且这个对象有实现then方法,那么会执行该then方法,then方法会传入resolve,reject函数。此时的promise状态取决于你调用了resolve,还是reject函数。这种模式也称之为: thenable1
2
3
4
5
6
7
8
9
10
11
12const promise = new Promise((resolve, reject) => {
resolve({
then(res, rej) {
rej("失败")
}
})
})
promise.then(res => console.log(res))
.catch(err => console.log(err))
// 输出内容:失败
Promise的实例方法
实例方法,存放在
Promise.prototype上的方法,也就是Promise的显示原型上,当我new Promise的时候,会把返回的改对象的 promise[[prototype]](隐式原型) === Promise.prototype (显示原型)即new返回的对象的隐式原型指向了Promise的显示原型
then方法
then方法可以接受参数,一个参数为成功的回调,另一个参数为失败的回调1
2
3
4
5
6
7
8const promise = new Promise((resolve, reject) => {
// resolve('request success')
reject('request error')
})
promise.then(res => console.log(res), rej => console.log(rej))
// 输出内容:request error如果只捕获错误,还可以这样写
- 因为第二个参数是捕获异常的,第一个可以写个
null或""占位
1
2
3
4
5
6
7
8const promise = new Promise((resolve, reject) => {
// resolve('request success')
reject('request error')
})
promise.then(null, rej => console.log(rej))
// 输出内容:request error- 因为第二个参数是捕获异常的,第一个可以写个
then
方法是有返回值的,它的返回值是promise1
2
3
4
5
6const promise = new Promise((resolve, reject) => {
resolve('执行成功')
})
console.log(promise.then(res => ({name:'张三', age:22})))
// 返回的是一个Promise对象
返回一个普通值 状态:fulfilled
1
2
3
4
5
6
7const promise = new Promise((resolve, reject) => {
resolve('执行成功')
})
promise.then(res => ({name:'张三', age:22}))
.then(res => console.log(res))
// {name: '张三', age: 22}返回一个普通值,则相当于主动调用
Promise.resolve,并且把返回值作为实参传递到then方法中。如果没有返回值,则相当于返回
undefined1
2
3
4
5
6
7
8const promise = new Promise((resolve, reject) => {
resolve('执行成功')
})
promise.then(res => (console.log(111)))
.then(res => console.log(res))
// 111
// undefined
明确返回一个promise状态:fulfilled
1
2
3
4
5
6
7
8
9
10const promise = new Promise((resolve, reject) => {
resolve('执行成功')
})
promise.then(res => {
return new Promise((resolve, reject) => {
resolve('返回的Promise对象resolve里面的内容')
})
}).then(res => console.log(res))
// 返回的Promise对象resolve里面的内容返回一个thenable对象 状态:fulfilled
1
2
3
4
5
6
7
8
9
10
11
12
13const promise = new Promise((resolve, reject) => {
resolve('hi ice')
})
promise.then(res => {
return {
then(resolve, reject) {
resolve('hi webice')
}
}
}).then(res => console.log(res))
//hi webice
catch方法
如果返回值明确一个promise或者thenable对象,取决于你调用了
resolve还是reject返回一个普通对象
1
2
3
4
5
6
7const promise = new Promise((resolve, reject) => {
reject('失败')
})
promise.catch(err => ({name:'张三', age: 22}))
.then(res => console.log(res)) // 如果这里调用.catch,什么也不会输出
// {name:'张三', age: 22}明确返回一个promise
1
2
3
4
5
6
7
8
9
10
11const promise = new Promise((resolve, reject) => {
reject('ice error')
})
promise.catch(err => {
return new Promise((resolve, reject) => {
reject('ice error promise')
})
}).catch(res => console.log(res))
//ice error promise返回thenable对象
1
2
3
4
5
6
7
8
9
10
11
12
13const promise = new Promise((resolve, reject) => {
reject('ice error')
})
promise.catch(err => {
return {
then(resolve, reject) {
reject('ice error then')
}
}
}).catch(res => console.log(res))
//ice error then
finally方法
- finally(最后),无论promise状态是fulfilled还是rejected都会执行一次
finally方法
Promise中的类方法/静态方法
Promise.reslove/Promise.reject
有的时候,你已经预知了状态的结果为fulfilled,则可以用这种简写方式
1
2
3Promise.resolve('abc')
//等价于
new Promise((resolve, reject) => resolve('abc'))有的时候,你已经预知了状态的结果为rejected,则可以用这种简写方式
1
2
3Promise.reject('error')
//等价于
new Promise((resolve, reject) => reject('error'))
Promise.all
fulfilled 状态
1 | |
- all方法的参数传入为一个可迭代对象,返回一个promise,只有三个都为
resolve状态的时候才会调用.then方法。 - 只要有一个promise的状态为rejected,则会回调
.catch方法
rejected状态
1 | |
- 当遇到rejectd的时候,后续的promise结果我们是获取不到,并且会把reject的实参,传递给catch的err形参中
上面的
Promise.all有一个缺陷,就是当遇到一个rejected的状态,那么对于后面是resolve或者reject的结果我们是拿不到的
- ES11 新增语法
Promise.allSettled,无论状态是fulfilled/rejected都会把参数返回给我们
Promise.allSettled
1 | |
- 该方法会在所有的Promise都有结果,无论是fulfilled,还是rejected,才会有最终的结果
其中一个promise没有结果
1 | |
Promise.race
- race(竞争竞赛)
- 优先获取第一个返回的结果,无论结果是fulfilled还是rejectd
1 | |
Promise.any
- 与race类似,只获取第一个状态为fulfilled,如果全部为rejected则报错
AggregateError
1 | |
async/await
Promise的语法糖,可以增加代码的可读性(用同步的思维写代码)
await后面的代码都是异步的
- async(异步的)
- async 用于申明一个异步函数
async内部代码同步执行
- 异步函数的内部代码执行过程和普通的函数是一致的,默认情况下也是会被同步执行
异步函数的返回值
普通函数主动返回什么就返回什么,不返回为
undefined异步函数的返回值特点
- 明确有返回一个普通值,相当于
Promise.resolve(返回值) - 返回一个thenable对象则由,then方法中的
resolve,或者reject有关 - 明确返回一个promise,则由这个promise决定
- 明确有返回一个普通值,相当于
异步函数的异常处理
- 如果函数内部中途发生错误,可以通过try catch的方式捕获异常
- 如果函数内部中途发生错误,也可以通过函数的返回值.catch进行捕获
1 | |
await 关键字
- 异步函数中可以使用
await关键字,普通函数不行 - await特点
- 通常await关键字后面都是跟一个Promise
- 可以是普通值
- 可以是thenable
- 可以是Promise主动调用
resolve或者reject
- 这个promise状态变为fulfilled才会执行
await后续的代码,所以await后面的代码,相当于包括在.then方法的回调中,如果状态变为rejected,你则需要在函数内部try catch,或者进行链式调用进行.catch操作
- 通常await关键字后面都是跟一个Promise
手写Promise加载图片
1 | |

参考文章
https://juejin.cn/post/7144308012952322084
Promise阅读代码题:https://juejin.cn/post/6844904077537574919