手写系列 | 实现一个Promise串行

182 阅读2分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第1天,点击查看活动详情

什么是串行

并行和串行都是通讯中数据传输的方式

  • 并行:同一时刻,可以传输多个 bit 的信号
  • 串行:同一时刻,只能传输一个 bit 的信号

蓝和绿色两个模块分别代表不同的事件,如吃饭和看电视,同时进行就是并行,吃完饭再看电视就是串行。区别在于它们执行的时机不同,如下图: image.png

在实现一个串行之前,需要对 Promise 有所了解。

Promise

Promise 是的一种异步解决方案,在 Promise 出现之前,异步的传统解决方案是回调函数。Promise 的出现解决了回调地狱问题。

Promise 是一个对象,可以获取异步操作的消息,共有三种状态:

  • pending
  • resolved
  • rejected

除此之外, Promise 还有.then()、.all()、.race() 等方法可调用。其中 Promise.all() 并行执行异步操作,在所有异步操作执行完后才执行回调,执行的顺序是有无序的

但是如果我们想要里面执行的顺序是有序的,又该如何操作呢?

reduce

reduce 可以将不同的 Promise 串联起来(串行),相当于 Promise().then().then() 的写法, 但使用 reduce 更简洁

语法:array.reduce(function(total, currentValue, currentIndex, arr), initialValue)

image.png

  • 注: reduce() 对于空数组不会执行回调函数

实现一个串行

实现思路:

  • 1.定义一个数组生成器(模式数据也可以直接写成一个固定值的数组),模拟接口的调用,执行时间随机
  • 2.使用Array.reduce()
  • 3.调用.then() ,此时串行完成

注意:在实现串行时,调用 reduce() 的是一个Function的数组,而不是Promise的数组(否则无法使用cur.next(),也无法串行成功,这是关键(曾经在这里踩过坑)

// 定义一个生成器 
const promiseGenerator = (num) => { 
return new Array(num).fill(0).map((_, index) => () => 
new Promise((resolve, reject) => { 
setTimeout(() => { 
console.log(index) 
resolve(index) 
}, Math.random() * 1000) 
}) 
) 
} 
const proArr = promiseGenerator(6) 
console.log(proArr) 
const myTask = proArr.reduce((prev,next)=> 
prev.then(()=> 
next() 
),Promise.resolve() 
); 
myTask.then(()=>console.log("all done."));

运行结果: image.png