前言
本篇文章旨在通过大量的Promise题目来消除人们对Promise的一些的恐惧,对那些原本比较害怕Promise的人(比如在下)比较有帮助,大佬请绕道!!!
我不会对各个问题加TAG——比如xxx题型之类的。开发场景是没有这些TAG来提醒我们的。
可以将一口气读完并答对全部问题为目标读文章,这样对消除恐惧感很有用(亲测有效)。就像闯关一样,多来几次自然就不怕了。
注意 本篇文章并不是每一个问题都是难的,而是难易交错!!
注意 本篇文章的内容在浏览器环境和 Node.js 环境中都适用
直接发车!🫏
题目1
const p = new Promise((resolve, reject) => {
console.log("Promise");
resolve("Resolved!");
});
console.log("Start");
p.then((res) => console.log(res));
console.log("End");
解析:
- 执行顺序为同步代码先执行,
Promise构造函数中的代码也是同步执行的。 Promise的then方法是微任务,会在当前宏任务执行完后执行。- 执行结果:
Promise Start End Resolved!
题目2
const p = new Promise((resolve, reject) => {
console.log("Promise");
resolve("Resolved!");
console.log("After Resolve");
});
p.then((res) => console.log(res));
console.log("End");
解析:
resolve调用后,Promise状态变为resolved,但后续代码仍会继续执行。- 执行结果:
Promise After Resolve End Resolved!
题目3
const p = new Promise((resolve, reject) => {
resolve("Resolved!");
console.log("Promise");
});
p.then((res) => console.log(res));
console.log("End");
解析:
resolve调用后,Promise状态变为resolved,但Promise构造函数中的代码仍会继续执行。- 执行结果:
Promise End Resolved!
题目4
const p = new Promise((resolve, reject) => {
setTimeout(() => {
console.log("Timer");
resolve("Resolved!");
}, 0);
});
console.log("Start");
p.then((res) => console.log(res));
console.log("End");
解析:
setTimeout是宏任务,会在当前宏任务执行完后进入下一轮事件循环。Promise的then方法是微任务,会在当前宏任务执行完后立即执行。- 注意,
resolve("Resolved!");还没执行的时候,p.then((res) => console.log(res));是无法执行的。 - 执行结果:
Start End Timer Resolved!
题目5
const p = new Promise((resolve, reject) => {
console.log("Promise");
resolve("Resolved!");
});
setTimeout(() => console.log("Timer"), 0);
p.then((res) => console.log(res));
console.log("End");
解析:
Promise的then方法是微任务,会在当前宏任务执行完后立即执行。setTimeout是宏任务,会在微任务执行完后执行。- 执行结果:
Promise End Resolved! Timer
题目6
Promise.resolve("Hello")
.then((res) => {
console.log(res);
return "World";
})
.then((res) => {
console.log(res);
});
解析:
Promise.resolve直接返回一个resolved状态的Promise。- 每次
then方法都会返回一个新的Promise,可以链式调用。 - 执行结果:
Hello World
题目7
Promise.resolve("Hello")
.then((res) => {
console.log(res);
throw new Error("Error!");
})
.catch((err) => {
console.log(err.message);
});
解析:
Promise链中抛出错误会被catch捕获。- 执行结果:
Hello Error!
题目8
Promise.resolve("Hello")
.then((res) => {
console.log(res);
return Promise.reject("Error!");
})
.catch((err) => {
console.log(err);
});
解析:
Promise.reject创建一个rejected状态的Promise,会被catch捕获。- 执行结果:
Hello Error!
题目9
Promise.resolve("Hello")
.then((res) => {
console.log(res);
return Promise.resolve("World");
})
.then((res) => {
console.log(res);
});
解析:
Promise.resolve可以将值包装为resolved状态的Promise。- 执行结果:
Hello World
题目10
Promise.resolve("Hello")
.then((res) => {
console.log(res);
throw new Error("Error!");
})
.then((res) => {
console.log('then:',res);
})
.catch((err) => {
console.log('catch:',err.message);
});
解析:
then方法中抛出的错误会被后续的catch捕获。- 执行结果:
Hello catch: Error!
题目11
const p1 = Promise.resolve("First");
const p2 = Promise.resolve("Second");
Promise.all([p1, p2]).then((res) => console.log(res));
解析:
Promise.all等待所有Promise完成,并返回一个包含所有结果的数组。- 执行结果:
["First", "Second"]
题目12
const p1 = Promise.resolve("First");
const p2 = new Promise((resolve) => setTimeout(() => resolve("Second"), 1000));
Promise.all([p1, p2]).then((res) => console.log(res));
解析:
Promise.all会等待所有Promise完成,即使有延迟。- 执行结果:
["First", "Second"]
题目13
const p1 = Promise.resolve("First");
const p2 = Promise.reject("Error!");
Promise.all([p1, p2]).then((res) => console.log(res)).catch((err) => console.log(err));
解析:
Promise.all中如果有任何一个Promise被拒绝,整个Promise.all会失败。- 执行结果:
Error!
题目14
const p1 = Promise.resolve("First");
const p2 = Promise.resolve("Second");
Promise.race([p1, p2]).then((res) => console.log(res));
解析:
Promise.race返回第一个完成的Promise的结果。- 执行结果:
First
题目15
const p1 = new Promise((resolve) => setTimeout(() => resolve("First"), 1000));
const p2 = Promise.resolve("Second");
Promise.race([p1, p2]).then((res) => console.log(res));
解析:
Promise.race返回第一个完成的Promise的结果。- 执行结果:
Second
题目16
const p1 = new Promise((resolve) => setTimeout(() => resolve("First"), 1000));
const p2 = new Promise((resolve) => setTimeout(() => resolve("Second"), 500));
Promise.race([p1, p2]).then((res) => console.log(res));
解析:
Promise.race返回第一个完成的Promise的结果。- 执行结果:
Second
题目17
const p1 = new Promise((resolve) => setTimeout(() => resolve("First"), 1000));
const p2 = Promise.resolve("Second");
Promise.all([p1, p2]).then((res) => console.log(res));
解析:
Promise.all会等待所有Promise完成。- 执行结果:
["First", "Second"]
题目18
const p1 = new Promise((resolve) => setTimeout(() => resolve("First"), 1000));
const p2 = new Promise((resolve) => setTimeout(() => resolve("Second"), 500));
const p3 = new Promise((resolve) => setTimeout(() => resolve("Third"), 1500));
Promise.all([p1, p2, p3]).then((res) => console.log(res));
解析:
Promise.all会等待所有Promise完成,并返回一个包含所有结果的数组。- 执行结果:
["First", "Second", "Third"]
题目19
const p1 = new Promise((resolve) => setTimeout(() => resolve("First"), 1000));
const p2 = new Promise((resolve, reject) => setTimeout(() => reject("Error!"), 500));
const p3 = new Promise((resolve) => setTimeout(() => resolve("Third"), 1500));
Promise.all([p1, p2, p3])
.then((res) => console.log(res))
.catch((err) => console.log(err));
解析:
Promise.all中如果有任何一个Promise被拒绝,整个Promise.all会失败。- 执行结果:
Error!
题目20
const p1 = new Promise((resolve) => setTimeout(() => resolve("First"), 1000));
const p2 = new Promise((resolve) => setTimeout(() => resolve("Second"), 500));
const p3 = new Promise((resolve) => setTimeout(() => resolve("Third"), 1500));
Promise.race([p1, p2, p3]).then((res) => console.log(res));
解析:
Promise.race返回第一个完成的Promise的结果。- 执行结果:
Second
题目21
const p1 = new Promise((resolve) => setTimeout(() => resolve("First"), 1000));
const p2 = new Promise((resolve, reject) => setTimeout(() => reject("Error!"), 500));
const p3 = new Promise((resolve) => setTimeout(() => resolve("Third"), 1500));
Promise.race([p1, p2, p3])
.then((res) => console.log(res))
.catch((err) => console.log(err));
解析:
Promise.race返回第一个完成的Promise的结果,无论它是resolved还是rejected。- 执行结果:
Error!
题目22
const p1 = new Promise((resolve) => setTimeout(() => resolve("First"), 1000));
const p2 = new Promise((resolve) => setTimeout(() => resolve("Second"), 500));
const p3 = new Promise((resolve) => setTimeout(() => resolve("Third"), 1500));
Promise.allSettled([p1, p2, p3]).then((res) => console.log(res));
解析:
Promise.allSettled会等待所有Promise完成,无论它们是resolved还是rejected,并返回一个包含所有结果的对象数组。- 执行结果:
[ { status: 'fulfilled', value: 'First' }, { status: 'fulfilled', value: 'Second' }, { status: 'fulfilled', value: 'Third' } ]
题目23
const p1 = new Promise((resolve) => setTimeout(() => resolve("First"), 1000));
const p2 = new Promise((resolve, reject) => setTimeout(() => reject("Error!"), 500));
const p3 = new Promise((resolve) => setTimeout(() => resolve("Third"), 1500));
Promise.allSettled([p1, p2, p3]).then((res) => console.log(res));
解析:
Promise.allSettled会等待所有Promise完成,无论它们是resolved还是rejected,并返回一个包含所有结果的对象数组。- 执行结果:
[ { status: 'fulfilled', value: 'First' }, { status: 'rejected', reason: 'Error!' }, { status: 'fulfilled', value: 'Third' } ]
题目24
const p1 = new Promise((resolve) => setTimeout(() => resolve("First"), 1000));
const p2 = new Promise((resolve) => setTimeout(() => resolve("Second"), 500));
const p3 = new Promise((resolve) => setTimeout(() => resolve("Third"), 1500));
Promise.any([p1, p2, p3]).then((res) => console.log(res));
解析:
Promise.any返回第一个resolved的Promise的结果,如果所有Promise都被拒绝,则返回一个AggregateError。- 执行结果:
Second
题目25
const p1 = new Promise((resolve, reject) => setTimeout(() => reject("Error1!"), 1000));
const p2 = new Promise((resolve, reject) => setTimeout(() => reject("Error2!"), 500));
const p3 = new Promise((resolve, reject) => setTimeout(() => reject("Error3!"), 1500));
Promise.any([p1, p2, p3])
.then((res) => console.log(res))
.catch((err) => console.log(err.errors));
解析:
Promise.any如果所有Promise都被拒绝,则返回一个AggregateError,其中包含所有错误信息。- 执行结果:
["Error1!", "Error2!", "Error3!"]
题目26
const p1 = new Promise((resolve) => setTimeout(() => resolve("First"), 1000));
const p2 = new Promise((resolve) => setTimeout(() => resolve("Second"), 500));
const p3 = new Promise((resolve) => setTimeout(() => resolve("Third"), 1500));
Promise.all([p1, p2, p3])
.then((res) => {
console.log(res);
return Promise.all([Promise.resolve("Fourth"), Promise.resolve("Fifth")]);
})
.then((res) => console.log(res));
解析:
- 第一个
Promise.all完成后,返回一个新的Promise.all,继续处理。 - 执行结果:
["First", "Second", "Third"] ["Fourth", "Fifth"]
题目27
const p1 = new Promise((resolve) => setTimeout(() => resolve("First"), 1000));
const p2 = new Promise((resolve) => setTimeout(() => resolve("Second"), 500));
const p3 = new Promise((resolve) => setTimeout(() => resolve("Third"), 1500));
Promise.race([p1, p2, p3])
.then((res) => {
console.log(res);
return Promise.race([Promise.resolve("Fourth"), Promise.resolve("Fifth")]);
})
.then((res) => console.log(res));
解析:
- 第一个
Promise.race完成后,返回一个新的Promise.race,继续处理。 - 执行结果:
Second Fourth
题目28
const p1 = new Promise((resolve) => setTimeout(() => resolve("First"), 1000));
const p2 = new Promise((resolve) => setTimeout(() => resolve("Second"), 500));
const p3 = new Promise((resolve) => setTimeout(() => resolve("Third"), 1500));
Promise.all([p1, p2, p3])
.then((res) => {
console.log(res);
throw new Error("Error!");
})
.catch((err) => console.log(err.message));
解析:
-
Promise.all完成后,then方法中抛出错误会被catch捕获。 -
执行结果:
["First", "Second", "Third"] Error!题目29
setTimeout(() => { console.log(1); }, 0); const p = new Promise((resolve) => { console.log(2); resolve(3) Promise.resolve(4).then(console.log); console.log(5); }).then(console.log); console.log(6);解析
- resolve(3) 是同步的,会立即改变 p 的状态。但是这个 promise 的 then 方法并不会马上进入 微队列 ,因为此时还没执行到 then 方法
- 执行结果:
2 5 6 4 3 1
题目30
console.log("Start"); const p1 = new Promise((resolve) => { console.log("Promise 1"); setTimeout(() => { console.log("Timer 1"); resolve("Resolved 1"); }, 0); }); p1.then((res) => { console.log(res); return new Promise((resolve) => { console.log("Promise 2"); resolve("Resolved 2"); }); }).then((res) => { console.log(res); }); setTimeout(() => { console.log("Timer 2"); }, 0); console.log("End");解析
- 需要注意的是,当 resolve("Resolved 1"); 未执行的时候,p1.then(...) 也会被放到微任务队列中。
- 注意,微任务优先于宏任务
- 执行结果:
Start Promise 1 End Timer 1 Resolved 1 Promise 2 Resolved 2 Timer 2
参考文章
最后
本人正在准备面试!后续会不断补充内容~