返回

亲历Promise.all、Promise.race、Promise.finally的巧妙构建

前端

从需求开始,踏上异步之路

迈入现代Web开发的舞台,异步编程成为不可忽视的强大工具。当我们处理复杂的并发任务时,Promise的出现可谓是应运而生,它为我们带来了更优雅的异步处理方式。Promise.all、Promise.race和Promise.finally作为Promise家族的重要成员,在实践中展现了各自的独特魅力。接下来,我们将手把手地从零开始构建它们,从编写代码到理解原理,一步步揭开它们的奥秘。

Promise.all:协同合作,齐心协力

首先,让我们走进Promise.all的世界。它的使命是将多个Promise集合起来,并等待它们全部完成。无论成功与否,它都会将所有结果汇集起来,交还给调用者。这种协同合作的方式,在某些场景下,能够为我们带来极大的便利。

手写实现Promise.all:从无到有,步步为营

想要深刻理解Promise.all的运作原理,最好的方式就是亲自动手实现它。让我们从一个简单的例子开始,逐步完善我们的代码,最终实现一个完整的Promise.all。

function promiseAll(promises) {
  // 结果数组
  const result = [];
  // 计数器
  let count = 0;

  return new Promise((resolve, reject) => {
    for (let i = 0; i < promises.length; i++) {
      promises[i]
        .then(res => {
          result[i] = res;
          count++;

          if (count === promises.length) {
            resolve(result);
          }
        })
        .catch(err => {
          reject(err);
        });
    }
  });
}

Promise.race:先声夺人,一马当先

接下来,让我们聚焦Promise.race。它扮演着截然不同的角色,它只关注第一个完成的Promise,无论成功与否,都会立即返回它的结果,而不会等待其他Promise完成。这种先声夺人的特性,在某些情况下,可以帮助我们优化程序的执行效率。

手写实现Promise.race:争分夺秒,胜负立现

想要理解Promise.race的精髓,同样需要动手实现它。我们将在上一节的基础上,对代码进行调整,最终打造出一个完整的Promise.race。

function promiseRace(promises) {
  return new Promise((resolve, reject) => {
    for (let i = 0; i < promises.length; i++) {
      promises[i]
        .then(res => {
          resolve(res);
        })
        .catch(err => {
          reject(err);
        });
    }
  });
}

Promise.finally:善始善终,画上句号

最后,我们来探索Promise.finally。它与前两者不同,无论Promise是成功还是失败,都会在最后执行一个回调函数。这种无论成败都需执行的特点,使其在某些情况下非常有用,例如,我们可以用它来处理资源的释放、错误的报告或最后的清理工作。

手写实现Promise.finally:始于足下,终于未来

为了完整地掌握Promise.finally,我们依然需要亲自编写代码。我们将继续对之前的代码进行改造,最终实现一个完备的Promise.finally。

Promise.prototype.finally = function (callback) {
  return this.then(
    res => {
      return Promise.resolve(callback()).then(() => res);
    },
    err => {
      return Promise.resolve(callback()).then(() => {
        throw err;
      });
    }
  );
};

结语:理论与实践,相得益彰

通过手写实现Promise.all、Promise.race和Promise.finally,我们不仅掌握了它们的具体实现细节,还深入理解了它们的运作原理和设计思想。理论与实践的结合,让我们对Promise的认识更上一层楼。希望本文能帮助你更好地理解和应用Promise,在异步编程的道路上走得更稳更远。