Promise使用
# 什么是Promise
Promise是一个类
在通过new创建Promise对象时,需要传入一个回调函数,称之为executor
- 这个回调函数会被立即执行,并且给传入两个回调函数
resolve
,reject
- 当调用
resolve
回调函数时,会执行Promise对象的then方法传入的回调函数 - 当调用
reject
回调函数时,会执行Promise对象的catch方法传入的回调函数
# Promise的执行过程
Promise在执行过程中划分为三个状态
- 待定(pending): 初始状态,既没有被兑现,也没有被拒绝;当执行executor中的代码时,处于该状态
- 已兑现(fulfilled): 意味着操作成功完成;执行了resolve时,处于该状态,Promise已经被兑现
- 已拒绝(reject): 意味着操作失败;执行了reject时,处于该状态,Promise已被拒绝。
Promise的状态一旦被确定下来了,就不会再更改,也不能再执行某一个回调函数来改变状态
# Executor
Executor是创建Promise时需要传入的一个回调函数,这个回调函数立即执行,并且传入两个参数
new Promise((resolve, reject) => {
console.log('executor代码')
})
2
3
# resolve传入不同的值
const p = new Promise((resolve) => {
setTimeout(() => {
resolve('p的resove');
}, 2000);
});
const promise = new Promise((resolve, reject) => {
/*
resolve中可以传入的值
1. 普通值 resolve("aaa")
resolve([
{ name: "Mac", price: 99999 },
{ name: "iPhone", price: 100 },
]);
2. resolve(promise)
如果resolve传入的值本身是Promise对象,那么当前的Promise状态会由传入的Promise来决定
3. resolve(thenable对象)
*/
resolve({
name: 'zs',
then: function(resolve){
resolve('thenable对象函数回调')
}
});
});
promise.then((res) => {
console.log("then中获取到结果:", res);
});
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
- 如果resolve传入一个普通的值或者对象,那么这个值会作为then回调的参数
- 如果resolve中传入的是另外一个Promise,那么这个新Promise会决定原Promise状态
- 如果resolve中传入的是一个对象那个,并且这个对象中有then方法,那么会执行该then方法,并且根据then方法的结果来决定Promise的状态
# Promise的then方法调用
const promise = new Promise((resolve, reject) => {
reject("failure");
});
// 写法一
promise
.then((res) => {
console.log("成功回调");
})
.catch((err) => {
console.log("失败回调");
});
// 写法二
promise.then(
(res) => {
console.log("成功回调");
},
(err) => {
console.log("失败回调");
}
);
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# then方法的多次调用
一个Promise的then方法是可以被多次调用的,每次调用都可以传入对应的fulfilled回调;当Promise状态变成fulfilled的时候,这些回调函数都会被执行
# then方法返回值
then方法本身是由返回值的,返回的是一个Promise,因此可以进行链式调用
then方法返回的Promise的状态
- 当then方法中的回调函数本身在执行的时候,那么处于pending状态
- 当then方法中的回调函数返回一个结果时,处于fulfilled状态,并且会将结果作为resolve的参数
- 返回一个普通的值
- 返回一个Promise
- 返回一个thenable值
- 当then方法抛出一个异常时,处于reject状态
# catch方法返回值
catch方法的返回值也是一个Promise对象,所以catch方法后main可以继续调用then方法或者catch方法
# resolve方法
then,catch,finally方法都属于Promise的实例方法,都是存放在Promise的prototype上的。
在某些情况下已经有一个现成的内容了,希望将其转成Promise来使用,这个时候可以使用Promise.resolve方法来完成。
Promise.resolve用法相当于new Promise,并且执行resolve方法。
resolve方法是Promise的一个类方法
Promise.resolve('zs')
// 相当于
new Promise((resolve) => resolve('zs'))
2
3
# reject方法
reject方法是Promise的一个类方法
reject方法的用法和resolve方法是一样的,只是会将Promise对象的状态设置为reject状态
# all方法
all方法也是Promise的一个类方法
- 其作用是将多个Promise包裹在一起形成一个新的Promise
- 新的Promise状态由包裹的所有Promise共同决定
- 当所有的Promise状态变成fulfilled状态时,新的Promise状态为fulfilled,并且会将所有的Promise的返回值组成一个数组
- 当有一个Promise状态为reject时,新的Promise状态为reject,并且会将第一个reject的返回值作为参数
const p1 = new Promise((resolve, reject) => {
// resolve('p1的Promise')
reject('p1 reject')
})
const p2 = new Promise((resolve, reject) => {
resolve('p2的Promise')
})
const p3 = new Promise((resolve, reject) => {
resolve('p3的Promise')
})
Promise.all([p1, p2, p3]).then(res => {
console.log(res)
}).catch(err => {
console.log(err)
})
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# allSettled方法
all方法存在一个缺陷,当其中一个Promise变成reject状态时,新的Promise就会立即变成对应的reject状态;那么对于resolve的,以及依然处于pending状态的Promise,是获取不到结果的。
在ES11中添加了新的API Promise.allSettled;该方法会在所有的Promise都有结果(settled),无论是fulfilled,还是reject时,才会有最终的状态;并且这个Promise的结果一定是fulfilled的
该方法的结果是一个数组,数组中存放这每一个Promise的结果,并且是对应一个对象的,这个对象中包含status状态,以及对应的value值
const p1 = new Promise((resolve, reject) => {
// resolve('p1的Promise')
reject("p1 reject");
});
const p2 = new Promise((resolve, reject) => {
resolve("p2的Promise");
});
const p3 = new Promise((resolve, reject) => {
resolve("p3的Promise");
});
Promise.allSettled([p1, p2, p3])
.then((res) => {
console.log(res);
})
.catch((err) => {
console.log(err);
});
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# race方法
多个Promise中其中任何一个Promise先有结果,那么这个结果就是最终的Promise的结果,
const p1 = new Promise((resolve, reject) => {
// resolve('p1的Promise')
reject("p1 reject");
});
const p2 = new Promise((resolve, reject) => {
resolve("p2的Promise");
});
const p3 = new Promise((resolve, reject) => {
resolve("p3的Promise");
});
Promise.race([p1, p2, p3])
.then((res) => {
console.log(res);
})
.catch((err) => {
console.log(err);
});
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# any方法
any方式是ES12中新增的方法,和race方法是类似的
any方法会等到一个fulfilled状态,才会决定新的Promise的状态
如果所有的Promise都是reject的,那么也会等到所有的Promise都会变成rejected状态
如果所有的Promise都是reject的,那么会报一个AggregateError错误