ES9:即时响应的 Promise.all() 和 Promise.race()

阅读时长 6 分钟读完

在前端开发中,常常需要处理多个异步操作并进行相应的处理。Promise则是在现代浏览器中解决异步操作的一个不错的工具。在ES9中,Promise.all()和Promise.race()的变化使得我们可以更加灵活地处理多个异步操作。

Promise.all()

Promise.all()用于将多个Promise实例包装成一个新的Promise实例,将所有的异步操作统一管理并等待所有异步操作都完成后执行回调函数:

其中,[promise1, promise2, promise3]是一个数组,数组里面的元素是Promise实例。如果三个Promise实例都成功resolve了,那么Promise.all()也将成功resolve,返回一个result1, result2, result3组成的数组。如果有任何一个Promise实例失败reject了,Promise.all()也将失败reject,并将失败原因传递给它的catch()方法。

在ES9里,Promise.all()新增了即时响应的特性。在传统Promise.all()中,只有所有的Promise实例都resolved或rejected后,整个Promise.all()才会resolve或reject。而在ES9中,只要一个Promise实例的状态变化了,Promise.all()就会立即响应。

下面是一个例子,其中promise2被延时2秒后才resolve:

-- -------------------- ---- -------
----- -------- - --- ----------------- ------- -- -
    ------------- -- -
        --------------------- -----------
        -------------------
    -- ------
---
----- -------- - --- ----------------- ------- -- -
    ------------- -- -
        --------------------- -----------
        -------------------
    -- ------
---
----- -------- - --- ----------------- ------- -- -
    ------------- -- -
        --------------------- -----------
        -------------------
    -- ------
---
---------------------- --------- ------------------------- -- -
    -------------------------- ---------- ---------
---------------- -- -
    ---------------------------- ---------- -------
---

执行以上代码可以发现,虽然promise2需要等2秒后才resolve,但是一旦promise1在1秒后resolve,Promise.all()就会立即响应并返回结果[result1, undefined, undefined],等promise2、promise3都resolve后才会再次响应并返回结果[result1, result2, result3]。

Promise.race()

Promise.race()与Promise.all()类似,都是将多个Promise实例包装成一个新的Promise实例。但是Promise.race()只要传入的多个Promise实例中有任意一个实例先resolve或reject,那么Promise.race()也将立即resolve或reject。如果先resolve或reject的Promise实例返回了结果,那么这个结果会被当作Promise.race()的结果,而其他结果会被忽略。

假设promise1需要1秒才能resolve,promise2需要2秒才能resolve,promise3需要3秒才能resolve,那么如果把它们放在Promise.race()中,那么在1秒后返回result1并立即resolve Promise.race(),而忽略promise2和promise3的resolve结果。

通过Promise.race(),我们可以实现一些超时的操作,例如设置一个Promise实例30秒内必须resolve,否则就reject。这可以通过两个Promise实例实现:一个成功resolve,一个失败reject。我们将这两个实例放入Promise.race()中,那么如果成功resolve的Promise实例先resolve,那么就可以在then()回调中处理成功逻辑;如果超时,那么失败reject的Promise实例会在catch()回调中处理。

下面是一个例子,其中promise1将在1秒后resolve,promise2将在3秒后resolve,promise3将在5秒后resolve,但Promise.race()只等待3秒:

-- -------------------- ---- -------
--- -------- - --- ----------------- ------- -- -
  ------------- -- -
    ----------------- -----------
  -- ------
---
--- -------- - --- ----------------- ------- -- -
  ------------- -- -
    ----------------- -----------
  -- ------
---
--- -------- - --- ----------------- ------- -- -
  ------------- -- -
    ----------------- -----------
  -- ------
---
--- ------- - --- ----------------- ------- -- -
  ------------- -- -
    ---------- ------- ------- -----------
  -- ------
---
----------------------- --------- --------- ----------------------- -- -
  --------------------------- ---------- --------
---------------- -- -
  ----------------------------- ---------- -------
---

执行以上代码可以发现,在3秒后,Promise.race()即完成,由于timeout实例的reject,Promise.race()会reject,并返回'timeout'错误信息,而promise1的结果会被忽略。

总结

ES9在Promise.all()和Promise.race()中新增了即时响应的特性,使得处理多个异步操作变得更加灵活和高效。在实际开发中,我们可以根据业务需求灵活运用Promise.all()和Promise.race()来解决多个异步操作的问题,达到更好的用户体验和更高的代码效率。

来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/645da480968c7c53b000cad5

纠错
反馈