用 Reduce 实现 Promise 串行执行

1 引言

本周精读的文章是 why-using-reduce-to-sequentially-resolve-promises-works,讲了如何利用 reduce 实现 Promise 串行执行。

在 async/await 以前 Promise 串行执行还是比较麻烦的,希望根据这篇文章可以理清楚串行 Promise 的思维脉络。

2 概述

除了依赖 async promise-fun 等工具库,最常用的队列操作就是 Array.prototype.reduce() 了:

let result = [1, 2, 5].reduce((accumulator, item) => {
  return accumulator + item;
}, 0); // <-- Our initial value.

console.log(result); // 8

最后一个值 0 是起始值,每次 reduce 返回的值都会作为下次 reduce 回调函数的第一个参数,直到队列循环完毕,因此可以进行累加计算。

那么将 reduce 的特性用在 Promise 试试:

function runPromiseByQueue(myPromises) {
  myPromises.reduce(
    (previousPromise, nextPromise) => previousPromise.then(() => nextPromise()),
    Promise.resolve()
  );
}

当上一个 Promise 开始执行(previousPromise.then),当其执行完毕后再调用下一个 Promise,并作为一个新 Promise 返回,下次迭代就会继续这个循环。

const createPromise = (time, id) => () =>
  new Promise(solve =>
    setTimeout(() => {
      console.log("promise", id);
      solve();
    }, time)
  );

runPromiseByQueue([
  createPromise(3000, 1),
  createPromise(2000, 2),
  createPromise(1000, 3)
]);

得到的输出是:

promise 1
promise 2
promise 3

3 精读

Reduce 是同步执行的,在一个事件循环就会完成(更多请参考 精读《Javascript 事件循环与异步》),但这仅仅是在内存快速构造了 Promise 执行队列,展开如下:

new Promise((resolve, reject) => {
  // Promise #1

  resolve();
})
  .then(result => {
    // Promise #2

    return result;
  })
  .then(result => {
    // Promise #3

    return result;
  }); // ... and so on!

Reduce 的作用就是在内存中生成这个队列,而不需要把这个冗余的队列写在代码里!

更简单的方法

感谢 eos3tion 同学补充,在 async/await 的支持下,runPromiseByQueue 函数可以更为简化:

async function runPromiseByQueue(myPromises) {
  for (let value of myPromises) {
    await value();
  }
}

多亏了 async/await,代码看起来如此简洁明了。

不过要注意,这个思路与 reduce 思路不同之处在于,利用 reduce 的函数整体是个同步函数,自己先执行完毕构造 Promise 队列,然后在内存异步执行;而利用 async/await 的函数是利用将自己改造为一个异步函数,等待每一个 Promise 执行完毕。

更多 Promise 拓展

天猪 同学分享的 promise-fun 除了串行 Promise 解决方案,还提供了一系列 Promise 功能拓展(有一些逐渐被 ES 标准采纳,比如 finally 已经进入 Stage 4),如果你的项目还无法使用 async/await,是不需要自己重新写一遍的,当然本文的原理还是需要好好理解。

Stage 相关可以进行拓展阅读 精读《TC39 与 ECMAScript 提案》

4 总结

Promise 串行队列一般情况下用的不多,因为串行会阻塞,而用户交互往往是并行的。那么对于并行发请求,前端按串行顺序接收 Response 也是一个有意思的话题,留给大家思考。

阅读全文
下载说明:
1、本站所有资源均从互联网上收集整理而来,仅供学习交流之用,因此不包含技术服务请大家谅解!
2、本站不提供任何实质性的付费和支付资源,所有需要积分下载的资源均为网站运营赞助费用或者线下劳务费用!
3、本站所有资源仅用于学习及研究使用,您必须在下载后的24小时内删除所下载资源,切勿用于商业用途,否则由此引发的法律纠纷及连带责任本站和发布者概不承担!
4、本站站内提供的所有可下载资源,本站保证未做任何负面改动(不包含修复bug和完善功能等正面优化或二次开发),但本站不保证资源的准确性、安全性和完整性,用户下载后自行斟酌,我们以交流学习为目的,并不是所有的源码都100%无错或无bug!如有链接无法下载、失效或广告,请联系客服处理!
5、本站资源除标明原创外均来自网络整理,版权归原作者或本站特约原创作者所有,如侵犯到您的合法权益,请立即告知本站,本站将及时予与删除并致以最深的歉意!
6、如果您也有好的资源或教程,您可以投稿发布,成功分享后有站币奖励和额外收入!
7、如果您喜欢该资源,请支持官方正版资源,以得到更好的正版服务!
8、请您认真阅读上述内容,注册本站用户或下载本站资源即您同意上述内容!
原文链接:https://www.shuli.cc/?p=17704,转载请注明出处。
0

评论0

显示验证码
没有账号?注册  忘记密码?