本篇博文是学习的掘金的一篇博文:【建议星星】要就来45道Promise面试题一次爽到底(1.1w字用心整理),经过自己一个个问题的学习,整理如下:

一.Promise的几道基础题


题目一 ✨

  1. const promise1 = new Promise((resolve,reject)=>{
  2. console.log('promise1')
  3. })
  4. console.log('1',promise1)
  5. // promise1
  6. // 1 Promise {<pending>}

先执行构造函数中的代码promise1,然后执行同步代码 1,由于没有resolve或者reject,此时状态为pending

题目二 ✨✨

  1. const promise = new Promise((resolve,reject)=>{
  2. console.log(1)
  3. resolve('success')
  4. console.log(2)
  5. })
  6. promise.then(()=>{
  7. console.log(3)
  8. })
  9. console.log(4)
  10. // 1 2 4 3
  1. 首先执行同步代码,打印出1
  2. 接着resolve的出现,只是将promise的状态改变成了resolved,将success这个值保存了下来。
  3. 会接着执行同步代码,输出2
  4. promsie.then是一个微任务,放入到微任务列表,等待宏任务执行完毕后,来执行微任务列表
  5. 继续执行本轮的宏任务,输出4
  6. 之后本轮宏任务执行完毕,检查微任务列表发现了这个promise..then,执行输出3

题目三 ✨

  1. const promise = new Promise((resolve, reject) => {
  2. console.log(1);
  3. console.log(2);
  4. });
  5. promise.then(() => {
  6. console.log(3);
  7. });
  8. console.log(4);
  9. // 1 2 4

在promise中没有resolve或者reject,因此promise.then不会执行

题目四 ✨

  1. const promise1 = new Promise((resolve, reject) => {
  2. console.log('promise1') // 1 执行构造函数中代码,打印输出
  3. resolve('resolve1') // 2 将promise1状态改为resolved,并将结果保存下来
  4. })
  5. const promise2 = promise1.then(res => { // 3. 将这个微任务,放入到微任务队列
  6. console.log(res) // 6.执行微任务,打印出结果 resolve1
  7. })
  8. console.log('1', promise1); //4 打印出promise1的状态为 resolved
  9. console.log('2', promise2); //5 打印出promise2的状态为 pending,宏任务执行完毕,寻找微任务队列,去到步骤6
  10. // promise1
  11. // 1 Promise{<resolved>}
  12. // 2 Promise{<pending>}
  13. // resolve1

题目五 ✨

  1. const fn = () => (new Promise((resolve, reject) => {
  2. console.log(1); //2.执行同步代码,打印1
  3. resolve('success') //3.更新fn的状态为resolved的Promise,且保存其值
  4. }))
  5. fn().then(res => { // 1.执行fn函数,.then为微任务列表,等待本轮宏任务执行完毕来检查
  6. console.log(res) // 4执行完,发现有微列表,打印success
  7. })
  8. console.log('start') // 4 本来宏任务,打印4
  9. // 1
  10. // start
  11. // success

fn是一个函数且直接返回的是一个Promise,主要是因为fn的调用在start之前的,所以fn里面的代码先执行

题目六 ✨

  1. const fn = () =>
  2. new Promise((resolve, reject) => {
  3. console.log(1); // 3.执行fn函数同步代码,打印1
  4. resolve("success"); // 4.将fn的结果Promise状态改为resolved,且保存这个值
  5. });
  6. console.log("start"); // 1.直接打印 start
  7. fn().then(res => { // 2.先去执行调用的fn函数,且将.then存入到微任务列表
  8. console.log(res); // 5.打印保存的这个值 success
  9. });
  10. // start
  11. // 1
  12. // success

这个fn的调用是在start之后才开始执行的,所以先打印start,再去执行fn这个函数

二、Promise结合setTimeout


题目七 ✨

  1. console.log('start') // 1.本轮宏任务开始,打印出 start
  2. setTimeout(() => { // 2. setTimeout是宏任务,会放到下一轮中去执行
  3. console.log('time') // 6.第二轮宏任务开始,打印出 time
  4. })
  5. Promise.resolve().then(() => { //3.then为微任务,等到本轮宏任务执行完毕,来检查
  6. console.log('resolve') // 5.检查到本轮微任务,打印出resolve,开始执行下一个宏任务
  7. })
  8. console.log('end') // 4.本轮宏任务打印出end,然后去检查本轮微任务
  9. // start
  10. // end
  11. // resolve
  12. // time

题目八 ✨✨

  1. const promise = new Promise((resolve, reject) => {
  2. console.log(1); // 1.执行同步代码,打印出1
  3. setTimeout(() => { // 2.下一轮宏任务才来执行,我们继续走我们本轮的宏任务
  4. console.log("timerStart"); // 7.第二次宏任务开始执行,打印出 timeStart
  5. resolve("success"); // 8.将promise状态改为resolved,且将结果保存
  6. console.log("timerEnd"); // 9.继续执行同步代码,打印出timeEnd
  7. }, 0);
  8. console.log(2); // 3.本轮的宏任务,直接打印出 2
  9. });
  10. promise.then((res) => { //4. .then是个微任务,等本轮宏任务执行完毕,再来检查,进入5
  11. //6.来检查了,但是promise还是pending状态,不执行,直接开始下一轮宏任务
  12. console.log(res); 宏任务 // 10 打印出success
  13. });
  14. console.log(4); // 5.本轮宏任务,打印出4,然后去检查本轮微任务
  15. // 1
  16. // 2
  17. // 4
  18. // timerStart
  19. // timerEnd
  20. // success

题目九 ✨✨

  1. // 1.本轮宏任务1开始
  2. setTimeout(() => { // 2.遇到setTimeout,放入到宏任务2去
  3. console.log('timer1'); // 4.宏任务2开始,打印出timer1
  4. setTimeout(() => { // 5.遇到setTimeout,放入到宏任务3后去,定义为4且宏任务2结束
  5. console.log('timer3') // 6. 宏任务4开始,打印出timer3
  6. }, 0)
  7. }, 0)
  8. setTimeout(() => { //3. 遇到setTimeout,放入到宏任务2之后去,定义为宏任务3
  9. console.log('timer2') // 6.宏任务3开始,打印出 timer2,宏任务3结束
  10. }, 0)
  11. console.log('start') // 4.宏任务1执行完毕,打印出start
  12. // start
  13. // timer1
  14. // timer2
  15. // timer3

加个Promise

  1. setTimeout(() => { // 1.加入到宏任务2中
  2. console.log('timer1'); // 4.宏任务2开始,打印出 timer1
  3. Promise.resolve().then(() => { //5.遇到.then,那么放入到宏任务2的微任务队列
  4. console.log('promise') // 6.没有其它宏任务,直接打印 promise
  5. })
  6. }, 0)
  7. setTimeout(() => { // 2.加入到宏任务2之后,定义为宏任务3
  8. console.log('timer2') //7.开始执行宏任务3,打印出 timer2
  9. }, 0)
  10. console.log('start') // 3.宏任务1执行完毕,打印出start
  11. // start
  12. // timer1
  13. // promise
  14. // time2

之所以先打印出promise是因为,第一个setTimeout为下一个宏任务队列,第二个setImeout为下下一个宏任务队列,因此在第二个宏任务队列执行完毕之后,会先去本轮的微任务队列中去查找是否有微任务。

题目十 ✨

  1. Promise.resolve().then(() => { // 1.遇到.then,放入到本轮微任务列表中去
  2. console.log('promise1'); // 4.查到本轮微任务列表,打印 promise1
  3. const timer2 = setTimeout(() => { //5.遇到setTimeout,放入到第三轮宏任务列表中去
  4. console.log('timer2') //7.第三轮宏任务开始,打印出timer2
  5. }, 0)
  6. });
  7. const timer1 = setTimeout(() => { //2.遇到setTimeout,放入到第二轮宏任务列表中去
  8. console.log('timer1') //5.打印出timer1
  9. Promise.resolve().then(() => { //6.宏任务2执行完毕后,发现微任务列表,打印出promise2
  10. console.log('promise2')
  11. })
  12. }, 0)
  13. console.log('start'); //3.打印出 start,查找本轮微任务列表
  14. // start
  15. // promise1
  16. // timer1
  17. // promise2
  18. // timer2

题目十一 ✨✨✨

  1. const promise1 = new Promise((resolve, reject) => {
  2. setTimeout(() => { // 1.放到下一轮宏任务中去
  3. resolve('success') //7.将promise1的状态修改为resoled,且保存值,查找还有没有微任务,查找到了.then
  4. }, 1000)
  5. })
  6. const promise2 = promise1.then(() => { //2.放到本轮微任务列表中去
  7. // 6.此时,promise1还没返回状态,不执行
  8. throw new Error('error!!!') // 8.throw相当于给了promise2状态为rejected,且打印出异常,开始执行下一轮宏任务
  9. })
  10. console.log('promise1', promise1) // 3.此时打印的promise1为pending状态
  11. console.log('promise2', promise2) // 4.此时打印的promise2为pending状态
  12. setTimeout(() => { // 5.放入到下一轮宏任务中去,找到到.then,去执行本轮微任务
  13. console.log('promise1', promise1) // 9.此时打印出promise1的状态为resolved,且值为success
  14. console.log('promise2', promise2) // 10. promise2此时的状态为rejected
  15. }, 2000)
  16. // promise1 Promise{pending}
  17. // promise2 Promise{pending}
  18. // 102 Uncaught (in promise) Error: error!!!
  19. // promise1 Promise{resoled:'success'}
  20. // promise2 Promise{rejected:'error!!!'}

题目十二 ✨✨

  1. const promise1 = new Promise((resolve, reject) => {
  2. setTimeout(() => { // 1.下一轮宏任务
  3. resolve("success"); //7.promise微resoled,且拿到了这个值进行保存
  4. console.log("timer1"); //8.打印4:打印出timer1
  5. }, 1000);
  6. console.log("promise1里的内容"); // 2.本轮同步代码,打印1
  7. });
  8. const promise2 = promise1.then(() => { //3.本轮微任务队列
  9. throw new Error("error!!!"); // 9.打印出5异常,且promise2为rejected状态,保存值
  10. });
  11. console.log("promise1", promise1); //4.打印2:promise1此时为pending状态
  12. console.log("promise2", promise2); //5.打印3:此时promise2位pending状态
  13. setTimeout(() => { // 6.下下一轮宏任务
  14. console.log("timer2"); // 10.打印出timer2
  15. console.log("promise1", promise1); // 11 打印6出success
  16. console.log("promise2", promise2); // 12 打印7出error!!!!
  17. }, 2000);
  18. // promise1里的内容
  19. // promise1 Promise{pending}
  20. // promise2 Promise{pending}
  21. // timer1
  22. // throw error
  23. // timer2
  24. // promise1 Promise{resolved}
  25. // promise2 Promise{rejected}

三、Promise中的then、catch、finally


题目十三 ✨

  1. const promise = new Promise((resolve, reject) => {
  2. resolve("success1");
  3. reject("error");
  4. resolve("success2");
  5. });
  6. promise
  7. .then(res => {
  8. console.log("then: ", res);
  9. }).catch(err => {
  10. console.log("catch: ", err);
  11. })
  12. // then success1

Promise中的状态一经改变,就不能再次进行改变了。

题目十四 ✨✨

  1. const promise = new Promise((resolve, reject) => {
  2. reject("error");
  3. resolve("success2");
  4. });
  5. promise
  6. .then(res => {
  7. console.log("then1: ", res);
  8. }).then(res => {
  9. console.log("then2: ", res);
  10. }).catch(err => {
  11. console.log("catch: ", err);
  12. }).then(res => {
  13. console.log("then3: ", res);
  14. })
  15. // catch error
  16. // then3 undefined

之所以最后是undefined,是因为catch()也会返回一个Promise,且由于这个Promise没有返回值

题目十五 ✨

  1. Promise.resolve(1)
  2. .then(res => {
  3. console.log(res);
  4. return 2;
  5. })
  6. .catch(err => {
  7. return 3;
  8. })
  9. .then(res => {
  10. console.log(res);
  11. });
  12. // 1 2

return 2 会被包装成 Promise(2)

题目十六 ✨

  1. Promise.reject(1)
  2. .then(res => {
  3. console.log(res);
  4. return 2;
  5. })
  6. .catch(err => {
  7. console.log(err);
  8. return 3
  9. })
  10. .then(res => {
  11. console.log(res);
  12. });
  13. // 1 3

题目十七 ✨ ✨

  1. const promise = new Promise((resolve, reject) => {
  2. setTimeout(() => {
  3. console.log('timer')
  4. resolve('success')
  5. }, 1000)
  6. })
  7. const start = Date.now();
  8. promise.then(res => {
  9. console.log(res, Date.now() - start)
  10. })
  11. promise.then(res => {
  12. console.log(res, Date.now() - start)
  13. })
  14. // timer
  15. // success 1000
  16. // success 10001

这里的.then之所以都会执行,是因为Promise中的.then或者.catch可以被调用多次。

题目十八 ✨ ✨

  1. Promise.resolve().then(() => {
  2. return new Error('error!!!')
  3. }).then(res => {
  4. console.log("then: ", res)
  5. }).catch(err => {
  6. console.log("catch: ", err)
  7. })
  8. // then error

返回任意一个非promise的值都会包裹成promise对象,这里的return new Error(‘error!!!’)被包装成 return Promise.resolve(new Error(‘error’)),如果需要抛出错误,可以使用Promise.reject()或者throw

题目十九 ✨ ✨

  1. const promise = Promise.resolve().then(() => {
  2. return promise;
  3. })
  4. promise.catch(console.err)
  5. // 结果报错:Uncaught (in promise) TypeError: Chaining cycle detected for promise #<Promise>

Promise的.then或者.catch中返回的值不能是promise本身,否则会造成死循环、报错

题目二十 ✨ ✨

  1. Promise.resolve(1)
  2. .then(2)
  3. .then(Promise.resolve(3))
  4. .then(console.log)
  5. // 1

.then或者.catch中的参数期望是函数,如果传入非函数那么就会发生值穿透,第一个then和第二个then中传入的都不是函数,因此发生了值的透传,将resolve(1)传入到了最后一个then中。

题目二十一 ✨

  1. Promise.reject('err!!!')
  2. .then((res) => {
  3. console.log('success', res)
  4. }, (err) => {
  5. console.log('error', err)
  6. }).catch(err => {
  7. console.log('catch', err)
  8. })
  9. // error,err!!!

then函数中会有两个参数,第一个为传入resolve结果的,第二个为reject,可以理解为.catch为.then的简写.then(undeifined,err)

  1. Promise.resolve()
  2. .then(function success (res) {
  3. throw new Error('error!!!')
  4. }, function fail1 (err) {
  5. console.log('fail1', err)
  6. }).catch(function fail2 (err) {
  7. console.log('fail2', err)
  8. })
  9. // fail2 error!

题目二十一 ✨ ✨ ✨

  1. Promise.resolve('1')
  2. .then(res => {
  3. console.log(res)
  4. })
  5. .finally(() => {
  6. console.log('finally')
  7. })
  8. Promise.resolve('2')
  9. .finally(() => {
  10. console.log('finally2')
  11. return '我是finally2返回的值'
  12. })
  13. .then(res => {
  14. console.log('finally2后面的then函数', res)
  15. })
  16. // 1
  17. // finally2
  18. // finally
  19. // finally2后面的then函数 2

为什么finally要在finally2中,看下面代码

  1. Promise.resolve('1')
  2. .finally(() => {
  3. console.log('finally1')
  4. throw new Error('我是finally中抛出的异常')
  5. })
  6. .then(res => {
  7. console.log('finally后面的then函数', res)
  8. })
  9. .catch(err => {
  10. console.log('捕获错误', err)
  11. })
  12. // finally1
  13. // 捕获错误 我是finally中抛出的异常

四、Promise中的all和race

题目二十二-all ✨

  1. function runAsync (x) {
  2. const p = new Promise(r => setTimeout(() => r(x, console.log(x)), 1000))
  3. return p
  4. }
  5. Promise.all([runAsync(1), runAsync(2), runAsync(3)])
  6. .then(res => console.log(res))
  7. // 1
  8. // 2
  9. // 3
  10. // [1,2,3]

有了all,可以并行执行多个异步操作,并且在一个回调中处理所有的返回数据,.all后面的then接收的是所有异步操作的结果。

题目二十三-all ✨ ✨

  1. function runAsync (x) {
  2. const p = new Promise(r => setTimeout(() => r(x, console.log(x)), 1000))
  3. return p
  4. }
  5. function runReject (x) {
  6. const p = new Promise((res, rej) => setTimeout(() => rej(`Error: ${x}`, console.log(x)), 1000 * x))
  7. return p
  8. }
  9. Promise.all([runAsync(1), runReject(4), runAsync(3), runReject(2)])
  10. .then(res => console.log(res))
  11. .catch(err => console.log(err))
  12. // 1
  13. // 3
  14. // 2
  15. // Error 2
  16. // 4

题目二十四-race ✨

  1. function runAsync (x) {
  2. const p = new Promise(r => setTimeout(() => r(x, console.log(x)), 1000))
  3. return p
  4. }
  5. Promise.race([runAsync(1), runAsync(2), runAsync(3)])
  6. .then(res => console.log('result: ', res))
  7. .catch(err => console.log(err))
  8. // 1
  9. // result 1
  10. // 2
  11. // 3

虽然race是赛跑且只会获取最先执行的那个结果,但是 2和3还是会去执行的。
应用场景是:为异步请求设置超时时间。

题目二十五-race✨

  1. function runAsync(x) {
  2. const p = new Promise(r =>
  3. setTimeout(() => r(x, console.log(x)), 1000)
  4. );
  5. return p;
  6. }
  7. function runReject(x) {
  8. const p = new Promise((res, rej) =>
  9. setTimeout(() => rej(`Error: ${x}`, console.log(x)), 1000 * x)
  10. );
  11. return p;
  12. }
  13. Promise.race([runReject(0), runAsync(1), runAsync(2), runAsync(3)])
  14. .then(res => console.log("result: ", res))
  15. .catch(err => console.log(err));
  16. // 0
  17. // result :Error:0
  18. // 1
  19. // 2
  20. // 3

all与race小结

  • Promise.all的作用是接收一组异步任务,然后并行执行异步任务,在所有异步任务执行完毕后才执行回调。
  • Promise.race也是接收一组异步任务,然后并行执行异步任务,只保留第一个先完成的异步执行结果,其它的结果会抛弃不用。
  • Promise.all.then中的结果与传入到all中的顺序是一致的。
  • all和race传入的数组如果有抛出异常的错误,那么只会抛出第一个错误。

五、async和await


在很多时候,async和await的解法和Promise差不多,但是有些又不一样。

题目二十六 ✨✨

  1. async function async1() {
  2. console.log("async1 start");
  3. await async2(); //会阻塞后面代码的执行
  4. console.log("async1 end");
  5. }
  6. async function async2() {
  7. console.log("async2");
  8. }
  9. async1();
  10. console.log('start')
  11. // async1 start
  12. // async2
  13. // start
  14. // async1 end

await后面的语句相当于放到了Prmise中,下一行以及之后的语句相当于放到了.then中。

  1. async function async1() {
  2. console.log("async1 start");
  3. new Promise(resolve => {
  4. console.log("async2")
  5. resolve()
  6. }).then(res => console.log("async1 end"))
  7. }
  8. async function async2() {
  9. console.log("async2");
  10. }
  11. async1();
  12. console.log("start")
  13. // async1 start
  14. // async2
  15. // start
  16. // async1 end
  1. async function async1() {
  2. console.log("async1 start");
  3. new Promise(resolve => {
  4. console.log('promise')
  5. })
  6. console.log("async1 end");
  7. }
  8. async1();
  9. console.log("start")
  10. // async1 start
  11. // promise
  12. // async1 end
  13. // start

题目二十七 ✨✨

  1. async function async1() {
  2. console.log("async1 start");
  3. await async2();
  4. console.log("async1 end");
  5. }
  6. async function async2() {
  7. setTimeout(() => {
  8. console.log('timer')
  9. }, 0)
  10. console.log("async2");
  11. }
  12. async1();
  13. console.log("start")
  14. // async1 start
  15. // async2
  16. // async1 end
  17. // start
  18. // timer

题目二十八 ✨✨✨

  1. async function async1() {
  2. console.log("async1 start"); // 2.打印1 async1 start
  3. await async2(); // 3.相当于new Promise,去里面执行同步代码
  4. console.log("async1 end"); // 8.打印4 async1 end
  5. setTimeout(() => { //9. 放入到下下下一轮宏任务
  6. console.log('timer1') // 11 打印7 timer1
  7. }, 0)
  8. }
  9. async function async2() {
  10. setTimeout(() => { //4. 放到下一步宏任务中去
  11. console.log('timer2') //9. 打印5 timer2
  12. }, 0)
  13. console.log("async2"); //5. 打印2 async2
  14. }
  15. async1(); //1.开始执行async1函数
  16. setTimeout(() => { // 6. 放入到下下一轮宏任务中去
  17. console.log('timer3') //10. 打印6 timer3
  18. }, 0)
  19. console.log("start") //7.打印3 start,然后检查本轮微任务
  20. // async1 start
  21. // async2
  22. // start
  23. // async1 end
  24. // timer2
  25. // timer3
  26. // timer1

题目二十九 ✨

  1. async function fn () {
  2. // return await 1234
  3. // 等同于
  4. return 123
  5. }
  6. fn().then(res => console.log(res))
  7. // 123

正常情况下,await后面是一个Promise对象,会返回改对象的结果

题目三十 ✨✨✨

  1. async function async1 () {
  2. console.log('async1 start'); // 2
  3. await new Promise(resolve => {
  4. console.log('promise1') // 3
  5. })
  6. console.log('async1 success');
  7. return 'async1 end'
  8. }
  9. console.log('srcipt start') // 1
  10. async1().then(res => console.log(res))
  11. console.log('srcipt end') // 4
  12. // srcipt start
  13. // async1 start
  14. // promise1
  15. // srcipt end

在async1中await后面的Promise是没有返回值的,也就是它的状态始终是pending状态,因此相当于一直在await,await,await却始终没有响应… 所以在await之后的内容是不会执行的,也包括async1后面的 .then。

题目三十一 ✨✨

  1. async function async1 () {
  2. console.log('async1 start'); // 2
  3. await new Promise(resolve => {
  4. console.log('promise1') // 3
  5. resolve('promise1 resolve')
  6. }).then(res => console.log(res)) //5
  7. console.log('async1 success'); //6
  8. return 'async1 end'
  9. }
  10. console.log('srcipt start') // 1
  11. async1().then(res => console.log(res)) //7
  12. console.log('srcipt end') // 4
  13. // srcipt start
  14. // async1 start
  15. // promise1
  16. // srcipt end
  17. // promise1 resolve
  18. // async1 success
  19. // async1 end

题目三十二 ✨✨

  1. async function async1 () {
  2. console.log('async1 start'); // 2
  3. await new Promise(resolve => {
  4. console.log('promise1') // 3
  5. resolve('promise resolve')
  6. })
  7. console.log('async1 success'); // 5
  8. return 'async1 end'
  9. }
  10. console.log('srcipt start') // 1
  11. async1().then(res => {
  12. console.log(res) // 6
  13. })
  14. new Promise(resolve => {
  15. console.log('promise2') // 4
  16. setTimeout(() => {
  17. console.log('timer') // 7
  18. })
  19. })
  20. // srcipt start
  21. // async1 start
  22. // promise1
  23. // promise2
  24. // async1 success
  25. // async1 end
  26. // timer

题目三十四 ✨✨

  1. async function async1() {
  2. console.log("async1 start"); // 2
  3. await async2();
  4. console.log("async1 end"); // 6
  5. }
  6. async function async2() {
  7. console.log("async2"); // 3
  8. }
  9. console.log("script start"); // 1
  10. setTimeout(function() {
  11. console.log("setTimeout");//8
  12. }, 0);
  13. async1();
  14. new Promise(function(resolve) {
  15. console.log("promise1"); // 4
  16. resolve();
  17. }).then(function() {
  18. console.log("promise2"); //7
  19. });
  20. console.log('script end') // 5
  21. // script start
  22. // async1 start
  23. // async2
  24. // promise1
  25. // script end
  26. // async1 end
  27. // promise2
  28. // setTimeout

题目三十五 ✨✨

  1. async function testSometing() {
  2. console.log("执行testSometing"); // 2
  3. return "testSometing";
  4. }
  5. async function testAsync() {
  6. console.log("执行testAsync"); // 6
  7. return Promise.resolve("hello async");
  8. }
  9. async function test() {
  10. console.log("test start..."); // 1
  11. const v1 = await testSometing();
  12. console.log(v1); //5
  13. const v2 = await testAsync();
  14. console.log(v2); // 8
  15. console.log(v1, v2);//9
  16. }
  17. test();
  18. var promise = new Promise(resolve => {
  19. console.log("promise start..."); // 3
  20. resolve("promise");
  21. });
  22. promise.then(val => console.log(val)); // 7
  23. console.log("test end..."); // 4
  24. // test start...
  25. // 执行testSometing
  26. // promise start...
  27. // test end...
  28. // testSometing
  29. // 执行testAsync
  30. // promise
  31. // hello async
  32. // testSometing hello async

六、async处理错误


题目三十六 ✨

  1. async function async1 () {
  2. await async2();
  3. console.log('async1');
  4. return 'async1 success'
  5. }
  6. async function async2 () {
  7. return new Promise((resolve, reject) => {
  8. console.log('async2') // 1
  9. reject('error')
  10. })
  11. }
  12. async1().then(res => console.log(res))
  13. // async2
  14. // Uncaught (in promise) error

await后面跟着一个rejected的promise,那么就会抛出错误,不再往下执行

  1. async function async1 () {
  2. console.log('async1');
  3. throw new Error('error!!!')
  4. return 'async1 success'
  5. }
  6. async1().then(res => console.log(res))

同上

题目三十七 ✨✨

  1. async function async1 () {
  2. try {
  3. await Promise.reject('error!!!')
  4. } catch(e) {
  5. console.log(e) // 2
  6. }
  7. console.log('async1'); // 3
  8. return Promise.resolve('async1 success')
  9. }
  10. async1().then(res => console.log(res)) //4
  11. console.log('script start')//1
  12. // script start
  13. // error!!!
  14. // async1
  15. // async1 success
  1. async function async1 () {
  2. await Promise.reject('error!!!')
  3. .catch(e => console.log(e))
  4. console.log('async1');
  5. return Promise.resolve('async1 success')
  6. }
  7. async1().then(res => console.log(res))
  8. console.log('script start')
  9. // 同上

七、综合题


题目三十八 ✨✨

  1. const first = () => (new Promise((resolve, reject) => {
  2. console.log(3); //1
  3. let p = new Promise((resolve, reject) => {
  4. console.log(7); //2
  5. setTimeout(() => {
  6. console.log(5); //6
  7. resolve(6);
  8. console.log(p) //7-1
  9. }, 0)
  10. resolve(1);
  11. });
  12. resolve(2);
  13. p.then((arg) => {
  14. console.log(arg); // 4-1
  15. });
  16. }));
  17. first().then((arg) => {
  18. console.log(arg); //5-2
  19. });
  20. console.log(4); //3
  21. // 3
  22. // 7
  23. // 4
  24. // 1
  25. // 2
  26. // 5
  27. // Promise{<resolved>: 1}

题目三十九 ✨✨

  1. const async1 = async () => {
  2. console.log('async1'); // 2-async1
  3. setTimeout(() => {
  4. console.log('timer1') //7-timer1
  5. }, 2000)
  6. await new Promise(resolve => {
  7. console.log('promise1') //3-promise1
  8. })
  9. console.log('async1 end')
  10. return 'async1 success'
  11. }
  12. console.log('script start'); // 1-script start
  13. async1().then(res => console.log(res));
  14. console.log('script end'); //4-script end
  15. Promise.resolve(1)
  16. .then(2)
  17. .then(Promise.resolve(3))
  18. .catch(4)
  19. .then(res => console.log(res)) //5-1
  20. setTimeout(() => {
  21. console.log('timer2') //6-timer2
  22. }, 1000)
  23. // script start
  24. // async1
  25. // promise1
  26. // script end
  27. // 1
  28. // timer2
  29. // timer1

这里需要注意的一点是:async函数中await的new Promise要是没有返回值的话则不执行后面的内容。

题目四十 ✨✨✨

  1. const p1 = new Promise((resolve) => {
  2. setTimeout(() => {
  3. resolve('resolve3');
  4. console.log('timer1') //3-timer1
  5. }, 0)
  6. resolve('resolve1');
  7. resolve('resolve2');
  8. }).then(res => {
  9. console.log(res) //1-resolve1
  10. setTimeout(() => {
  11. console.log(p1) //4-p1返回的是finally最终的值,所以也是undefined
  12. }, 1000)
  13. }).finally(res => { //finally中是接收不到Promise结果的,这个res是个迷惑项
  14. console.log('finally', res) // 2-finally-undefined
  15. })
  16. // resolve1
  17. // finally,undefined
  18. // timer1
  19. // Promise {resolve:undefined}

八、大厂面试题

题目四十一—使用Promise每秒输入1 2 3

  1. const arr = [1, 2, 3]
  2. arr.reduce((p, x) => {
  3. return p.then(() => {
  4. return new Promise(r => {
  5. setTimeout(() => r(console.log(x)), 1000)
  6. })
  7. })
  8. }, Promise.resolve())

题目四十二—使用Promise实现红绿灯交替重复亮

  1. // 红灯3秒亮一次,黄灯2秒亮一次,绿灯1秒亮一次
  2. function red {
  3. console.log('red')
  4. }
  5. function yellow(){
  6. console.log('yellow')
  7. }
  8. function green(){
  9. console.log('green')
  10. }
  11. const light = function (timer, cb) {
  12. return new Promise(resolve => {
  13. setTimeout(() => {
  14. cb()
  15. resolve()
  16. }, timer)
  17. })
  18. }
  19. const step = function () {
  20. Promise.resolve().then(() => {
  21. return light(3000, red)
  22. }).then(() => {
  23. return light(2000, green)
  24. }).then(() => {
  25. return light(1000, yellow)
  26. }).then(() => {
  27. return step()
  28. })
  29. }
  30. step();

题目四十三:封装一个异步加载图片的方法

  1. function loadImg(url){
  2. return new Promise((resolve,reject)=>{
  3. const img = new Image();
  4. img.onload = function(){
  5. console.log('一张图片加载完成')
  6. resolve(img)
  7. }
  8. img.onerror = function() {
  9. reject(new Error('Could not load image at' + url));
  10. };
  11. img.src = url;
  12. })
  13. }