急需收集看到的Promise练习题,方便各位练习,上两期可看
Promise练习题 II
Promise练习题 I
问下面代码的输出顺序
const first = () => (new Promise((resolve, reject) => {
console.log(3);
let p = new Promise((resolve, reject) => {
console.log(7);
setTimeout(() => {
console.log(5);
resolve(6);
}, 0)
resolve(1);
});
resolve(2);
p.then((arg) => {
console.log(arg);
});
}));
first().then((arg) => {
console.log(arg);
});
console.log(4);
上面这个代码结合了同步异步的输出,两个Promise包裹,以及Promise的状态只会改变一次的知识点
首先从同步输出开始
- first首先被调用,此时开始执行
first
的内部代码
1.1 那么首先输出的是console.log(3)
1.2 之后first
内还包裹了一个Promise,并且也调用了then
方法,那么还是会先输出这个Promise内部的同步代码console.log(7)
1.3 之后是一个定时器是一个宏任务,先挂起不执行,之后是resolve(1)
,将内部Promise的状态改为成功,并且传参1
1.4resolve(2)
将外部Promise的状态改为成功,并且传参2
1.5 调用了内部Promise的then
方法,接受上面的传参1,但是这里的then是属于微任务,所以不执行
整个first内部执行完成 -
first().then
,接收到传参2,但是因为then
方法是个微任务,所以也是先不执行 -
console.log(4)
是最后一个同步任务直接输出
那么同步任务输出顺序是3 7 4
之后是上面挂起的微任务
- 内部Promise的
then
方法开始输出1 - 外部Promise的
then
方法开始输出2
所以微任务输出顺序是1 2
最后是宏任务
上面只挂起了一个定时器宏任务,当微任务执行完成之后,开始执行,先输出console.log(5)
内部还有一个resolve(6)
但是之前已经resolve(1)
了,Promise的状态只能更改一次,所以这句不会执行
最后宏任务输出5
按照同步>微任务>宏任务的执行顺序,输出3 7 4 1 2 5即为最后结果
asyncThing1()
.then(function() {
return asyncThing2();
})
.then(function() {
return asyncThing3();
})
.catch(function(err) {
return asyncRecovery1();
})
.then(
function() {
return asyncThing4();
},
function(err) {
return asyncRecovery2();
}
)
.catch(function(err) {
console.log("Don't worry about it");
})
.then(function() {
console.log("All done!");
});
这里的所有函数都理解为封装的异步方法,题目来源于JavaScript Promises: An introduction,是一个开放性的题目,主要针对then
和catch
的参数,题目答案如下
已经知道Promise有两种情况,成功就走
then
,失败就走catch
总结要点:
catch
能够捕获前面所有的异步异常,例如图中的asyncThing1()
asyncThing2()
asyncThing3()
的错误都会被asyncRecovery1()
捕获catch是捕捉所有为处理的错误,then只负责前面的那个Promise