一道关于Promise面试题的分析

Promise已经成为前端界必须掌握的技能了,哪怕不了解promise的内部机制,也一定用过相关的api。那么一个promise和setTimeout结合的面试题就非常时候学习promise的内部机制了。

首先,先看题目:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
const first = () => (new Promise((resovle,reject)=>{
console.log(3);
let p = new Promise((resovle, reject)=>{
console.log(7);
setTimeout(()=>{
console.log(5);
resovle(6);
},0)
resovle(1);
});
resovle(2);
p.then((arg)=>{
console.log(arg);
});
}));
first().then((arg)=>{
console.log(arg);
});
console.log(4);

promise对象只有三种状态: pending,fulfilledrejected。状态会变化且只会变化一次,有两种可能:从pending变成fulfilled;从pending变成rejeced

上述题目,调用处仅有一次,即:

1
2
3
first().then((arg)=>{
console.log(arg);
});

在任务流里,首先开启了一个first的new Promise操作,输出了3。然后遇到了p,开启另一个new Promise操作,输出了7,遇到定时器,定时器要放入下一轮的任务队列里。
接着往下走,是p的then(简称p.then),加入队列任务,该任务是在定时器之前的。之后是first的then任务(简称f.then)。
延迟的任务队列排好以后,执行最后一行,输出4
目前,顺序流执行下来,输出是3,7,4
再执行排列的任务,p.then和f.then,输出1,2.
最后执行定时器,输出5。由于promise对象的状态只会变化一次,所以定时器里的resolve(6)是不会执行的。

最终的输出结果是3,7,4,1,2,5

Snapline wechat
扫码关注我的公众号“约翰柠檬的唱片店”
Buy me a cup of Coffee