首页 > 解决方案 > Promise.resolve 与 Promise.resolve().then()

问题描述

之前在这里提出的一个问题,与这个问题的标题完全相同,被回答为“你不应该使用那个,而是使用这个”,我想知道它的作用,而不是我还能做什么,这是关于理解不是简单的复制粘贴。

我的问题很简单,这三种方法在创建 Promise 时有什么区别?

const API = (item, fail) =>
  new Promise((resolve, reject) => {
    if (fail) reject(item + ' ...with an error');
    setTimeout(() => resolve(item), 1000);
  });

(async () => {
  const pro1 = Promise.resolve(API('I am inside resolve'));
  const pro2 = Promise.resolve(API('I am inside resolve', true));

  const pro3 = Promise.resolve().then(() => API('I am thenable'));
  const pro4 = Promise.resolve().then(() => API('I am thenable', true));

  const pro5 = new Promise((resolve) => resolve(API('I am a new promise')));
  const pro6 = new Promise((resolve) => resolve(API('I am a new promise', true)));

  const store = [pro1, pro2, pro3, pro4, pro5, pro6];

  const results = await Promise.allSettled(store);

  for (const { status, value, reason } of results) {
    if (status === 'fulfilled') console.log(value)
    else console.log(reason)
  }
})();

标签: javascriptes6-promise

解决方案


不同之处在于要完成的工作。虽然所有这些方法都是有效的,但它们具有不同的成本和可预测性。

  1. Promise.resolve()生成单个已解析的 Promise 实例,并根据提供给调用 JS 引擎的值有信息来优化它。它使所有工作都在对 JS 引擎的底层代码(通常是 C++,但可能是 Java 或 WASM)的一次调用中完成。所以它永远是最好的选择。
  2. Promise.resolve().then(() => API(/*...*/))产生几个 Promise 实例:一个在Promise.resolve(),另一个在.then()调用。它还分配更多内存并在 JS 和引擎之间进行多次(3 次或更多)冗余跳转。它几乎不可优化,需要执行密集的启发式算法才能确定此调用是否可优化。这是最糟糕的选择。
  3. new Promise((resolve) => resolve(API(/* ... */))分配一个函数和一个 Promise 实例,在 JS 和引擎之间进行两次跳转。由于 JS 的性质,优化此调用更加困难。

推荐阅读