Promise恐惧消除器

245 阅读7分钟

前言

本篇文章旨在通过大量的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构造函数中的代码也是同步执行的。
  • Promisethen方法是微任务,会在当前宏任务执行完后执行。
  • 执行结果:
    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是宏任务,会在当前宏任务执行完后进入下一轮事件循环。
  • Promisethen方法是微任务,会在当前宏任务执行完后立即执行。
  • 注意,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");

解析

  • Promisethen方法是微任务,会在当前宏任务执行完后立即执行。
  • 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返回第一个resolvedPromise的结果,如果所有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 的状态。但是这个 promisethen 方法并不会马上进入 微队列 ,因为此时还没执行到 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
      

参考文章

最后

本人正在准备面试!后续会不断补充内容~