Promise
先看代码
1 | function 摇骰子(){ |
这是一个异步任务,那么问题来了 异步任务什么时候执行?
- 改写了一下
1 | function 摇骰子(){ |
面试中的 微任务/宏任务
看这样一段代码
1 | <!DOCTYPE html> |
微任务/宏任务这些前端名词的前因后果
- 本来是没有 Promise的 在 ES6之前,ES6之后才有了 Promise这种异步
- 以前的JS非常单纯只有两个东西
- 当前任务 执行的代码(同步代码)
- 延时任务 setTimeout / setInterval
ES6以前
- 当前代码 如
console.log(1)
- 异步队列 setTimeout
1 | console.log(1) |
所以以前的js非常好理解,就是我有个当前要执行的任务,和有个等待执行的任务
ES6之后
前端觉得回调太蛋疼了,于是加了个 Promise
- 宏任务 – 异步队列1(原来的异步队列 setTimeout)
- 微任务 – 异步队列2 (Promise 使用)
- 同步代码
1 | // 伪代码 |
于是分别给 异步队列1 / 异步队列2 取了个名字叫做 宏任务 / 微任务
如果队列里有任务,先把 微任务 做完,再去做 宏任务
Promise 其他API
继续以摇骰子为例
1 | function 摇骰子(){ |
Promise.resolve(result) 制造一个成功(或失败)
1
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// 制造成功
// 你想造假一直 摇6
function 摇6的骰子(){
return new Promise((resolve, reject)=>{
resolve(6)
})
}
function 摇6的骰子2(){
return Promise.resolve(6)
}
// 摇6的骰子
// 摇6的骰子().then((res)=>{console.log(res)})
// 摇6的骰子2().then((res)=>{console.log(res)})
// 制造失败
function 摇骰子返回失败(){
return Promise.resolve(
new Promise((resolve,reject)=>reject())
)
}
摇骰子返回失败().then((res)=>{console.log(res)})Promise.reject(reason) 制造一个失败
1
2
3
4
5
6
7
8
9
10
11
12function 摇坏的骰子(){
return new Promise((resolve, reject)=>{
reject('坏了')
})
}
function 摇坏的骰子2(){
return Promise.reject('坏了')
}
摇坏的骰子().then(null,(reason)=>console.log(reason))
摇坏的骰子2().then(null,(reason)=>console.log(reason))Promise.all(数组) 等待全部成功,或有一个失败
1
2
3
4
5
6
7
8
9
10
11
12
13// 所有人都成功了,才叫成功 返回所有成功的结果
Promise.all([Promise.resolve(1),Promise.resolve(2),Promise.resolve(3)]).then((res)=>{console.log(res)})
// 打印 [1,2,3]
// 某个失败 返回失败
Promise.all([Promise.resolve(1),Promise.resolve(2),Promise.reject('错了3')]).then((res)=>{console.log(res)},(err)=>{console.log(err)})
// 打印 "错了3"
Promise.all([Promise.resolve(1"),Promise.reject('错了2'),Promise.reject('错了3')]).then((res)=>{console.log(res)},(err)=>{console.log(err)})
// 打印 "错了2"
Promise.all([Promise.reject("错了1"),Promise.reject('错了2'),Promise.reject('错了3')]).then((res)=>{console.log(res)},(err)=>{console.log(err)})
// 打印 "错了1"- 所以 Promise.all 非常没用,因为有一个失败就返回了不等所有的结果
- 请使用
Promise.allSettled
Promise.race(数组) 等待第一个状态改变
1
同时发很多请求,只要又一个成功了,就成功,或者一个失败了就失败
Promise.allSettled(数组) 等待全部状态改变,目前处于 Stage-4(板上钉钉的实现)
1
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
28
29
30Promise.allSettled([Promise.resolve(1),Promise.resolve(2),Promise.resolve(3)]).then((res)=>{console.log(res)},(err)=>{console.log(err)})
// resolve 打印
/*
[
{status: "fulfilled", value: 1},
{status: "fulfilled", value: 2},
{status: "fulfilled", value: 3}
]
*/
Promise.allSettled([Promise.resolve(1),Promise.reject('错了2'),Promise.resolve(3)]).then((res)=>{console.log(res)},(err)=>{console.log(err)})
// reject 打印
/*
[
{status: "fulfilled", value: 1},
{status: "rejected", reason: "错了2"},
{status: "fulfilled", value: 3}
]
*/
Promise.allSettled([Promise.reject("错了1"),Promise.reject('错了2'),Promise.reject('错了3')]).then((res)=>{console.log(res)},(err)=>{console.log(err)})
// reject 打印
/*
[
{status: "rejected", reason: "错了1"},
{status: "rejected", reason: "错了2"},
{status: "rejected", reason: "错了3"}
]
*/
由于
Promise.allSettled
很多浏览器不支持,我们依旧无法使用
所以用 Promise.all 实现
1 | // 假设还是三个 promise 任务 第一个和第二个会失败 |