初学Promise对象,异步基础
基础
三个状态(重要)
- pendding 等待状态
- fullfilled 完成状态
- rejected 失败状态
状态流向以及回调函数resolve和reject
Promise状态流向只有两种,而且状态一旦改变,则不会再变
- 调用reolve函数,则 pendding => fullfilled
- 调用rejecte函数,则pendding => rejected
- 只接收第一个参数调用后改变状态,其他的忽略
1
2
3
4
5
6
7
|
const promise = new Promise((resolve, reject) => {
resolve(1);
reject(2); // 被忽略
})
console.log(promise)
// PromiseState : fullfilled
// PromiseResult: 1
|
消费者 .then、.catch
最重要最基础的一个就是 .then
个人见解就是then就是对Promise对象的一个总结反馈,判断对象的状态并且执行fullfilled后的函数
下面例子,可自己通过注释选择resolve还是reject
1
2
3
4
5
6
7
8
9
10
|
let promise = new Promise(function(resolve, reject) {
// setTimeout(() => resolve("done!"), 1000);
setTimeout(() => reject(new Error("Whoops!")), 1000);
});
// reject 运行 .then 中的第二个函数
promise.then(
result => alert(result), // 不运行
error => alert(error) // 1 秒后显示 "Error: Whoops!"
);
|
如果我们只对某个状态的情况感兴趣,那么我们可以只为 .then 提供一个函数参数:
1
2
3
4
5
6
7
|
let promise = new Promise(resolve => {
setTimeout(() => resolve("done!"), 1000);
// setTimeout(() => reject("fail!"), 1000);
});
promise.then(alert); // 1 秒后显示 "done!"
// promise.catch(alert); // 1 秒后显示 "fail!"
|
实际情况成功的情况较为常见,并且.then和.catch也可以通过链式写法
1
2
3
4
5
|
new Promise((resolve, reject) => {
resolve(42);
}).then(value => {
console.log(value); // 输出: 42
});
|
Promise.API
await+async
- Promise 通过链式调用(如 .then() 和 .catch())管理异步操作的成功或失败;
- async 修饰的函数总会返回一个 Promise,无论返回的是普通值还是 Promise 本身;
- await await语句之后的代码处于微队列,用于暂停 async 函数的执行,等待后面的 Promise 解析完成,然后直接获得解析结果,从而让异步代码写起来更像同步代码,避免了冗长的 .then() 链。
await 等待的不一定是promise对象,也有可能为await 1; ==> await Promise.resolve(1)
Promise.all
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
Promise.all([
// 每个数组对象都是**异步微任务**,因此1和2瞬间输出
// 对象5 需要等待 对象4 await执行完毕后执行,即3秒后输出3
new Promise(resolve => setTimeout(() => resolve(4), 4000)), // 对象0,value4
console.log(1), // 对象1,undefined(不是promise对象)
new Promise(resolve => setTimeout(() => resolve(2), 2000)), // 对象2,value2
console.log(2), // 对象3,undefined
await new Promise(resolve => setTimeout(() => resolve(3), 3000)), // 对象4,value3
console.log(3), // 对象5,undefined
]).then((res) => {
console.log(res);
}) // 4秒后所有异步任务执行完毕,输出
[
0:1,
1:undefined,
2:2,
3:undefined,
4:3,
5:undefined
]
|
全部完成才会运行.then,如果有某一个失败,则不执行.then
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
Promise.allSettled([
new Promise(resolve => setTimeout(() => resolve(4), 4000)),
console.log(1),
new Promise((resolve,reject) => setTimeout(() => reject(2), 2000)), // 这里使用reject
console.log(2),
await new Promise(resolve => setTimeout(() => resolve(3), 3000)),
console.log(3),
]).then((res) => {
console.log(res);
})
[
0:1,
1:undefined,
2:2,
3:undefined,
4:3,
5:undefined
]
|
Promise.allsettled
如果任意的 promise reject,则 Promise.all
整个将会 reject。当我们需要 所有 结果都成功时,它对这种“全有或全无”的情况很有用
Promise.allSettled
等待所有的 promise 都被 settle,无论结果如何。结果数组会是这样的:
- 对成功的响应,结果数组对应元素的内容为
{status:"fulfilled", value:result}
,
- 对出现 error 的响应,结果数组对应元素的内容为
{status:"rejected", reason:error}
。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
Promise.allsettled([
new Promise(resolve => setTimeout(() => resolve(4), 4000)),
console.log(1),
new Promise((resolve,reject) => setTimeout(() => reject(2), 2000)), // 这里使用reject
console.log(2),
await new Promise(resolve => setTimeout(() => resolve(3), 3000)),
console.log(3),
]).then((res) => {
console.log(res);
})
// 控制台输出
[
0:{status:fullfiled,value:4},
1:{status:fullfiled,value:undefined},
2:{status:rejected,reson:2},
3:{status:fullfiled,value:undefined},
4:{status:fullfiled,value:3},
5:{status:fullfiled,value:undefined},
]
|
参考文献
js小红书
ECMAScript 6 入门
一道让我失眠的 Promise 面试题