Promise的并行和串行

小编 2026-06-05 阅读:1629 评论:0
Promise 并行这个功能Promise自身已经提供,不是本文的重点。主要是依赖Promise...

Promise 并行

这个功能Promise自身已经提供,不是本文的重点。主要是依赖Promise.all和Promise.race。
Promise.all是所有的Promise执行完毕后(reject|resolve)返回一个Promise对象。
Promise.race是任意一个Promise对象执行完毕后返回一个Promise对象。
有人可能会说,不是Promise对象reject的时候要catch么,这个嘛,.catch只是.then的一种变体。
详情可以参考Promise.allPromise.race

Promise 串行

这个Promise对象本身没有提供,也是本文的重点。
Promise一单开始执行,执行上是不存在串行执行的,你想想,比如典型的计时的Promise。

const p1 =new Promise((resolve, reject) => {        setTimeout(function () {            resolve(1)        }, 1000)    })const p2 =new Promise((resolve, reject) => {        setTimeout(function () {            resolve(2)        }, 2000)    })

像上面这种,你怎么去串行,当然是不行的。所以,思路得改变。把上面的Promise修改为如下

const p1 = function () {        return new Promise((resolve, reject) => {            setTimeout(function () {                resolve(1)            }, 1000)        })    },    p2 = function () {        return new Promise((resolve, reject) => {            setTimeout(function () {                resolve(2)            }, 2000)        })    },

哦,不是直接的Promise对象,再利用Promise.then时执行该p1(),使得Promise链条得以继续。

/** * 顺序执行Promise,并返回结果 * @param {返回promise的函数集合} promises  * @param {每一步的回调函数,非异步,可以考虑后期支持} cb  * @param {附加参数} args  */function sequence(promises, cb, ...args) {    const p = Promise.resolve(),        len = promises.length    if (len <= 0) {        return p    }    let i = 0    //如果cb不是函数    if (typeof cb !== 'function') {        cb = null        args = [cb, ...args]    }    function callBack(...params) {        return p.then(r => {            return promises[i](r, ...params)        }).then(r => {            ++i            cb && cb(r, i, ...params)            return i > len - 1 ? Promise.resolve(r) : callBack(...params)        })    }    return callBack(...args)}

先解释一些一下参数

  • promises: 返回Promise对象的集合
  • cb 执行完每个Promise的回调,传入的参数有
    • r: 上一次Promise执行完毕的返回结果
    • i: 当前Promise的索引值
    • params:其他的传入参数
  • args 其他的传入参数

返回来看,核心就是callback函数,他会顺序执行promises的函数返回Promise,然后取检查是否执行到最后,如果还有Promise等待执行,就调用callback,继续执行下一个,反之,结束。

我们来看一个简单的例子

const p1 = function () {        return new Promise((resolve, reject) => {            setTimeout(function () {                resolve(1)            }, 1000)        })    },    p2 = function () {        return new Promise((resolve, reject) => {            setTimeout(function () {                resolve(2)            }, 2000)        })    },    p3 = function () {        return new Promise((resolve, reject) => {            setTimeout(function () {                resolve(3)            }, 3000)        })    }function printTime() {    console.log(new Date().toLocaleString(), ...arguments)}const promises = [p1, p2, p3]sequence(promises, function (r, i, ...args) {    console.log('result:' + r, 'index:' + i, 'args:' + args)}, {    a: 1,    b: 2},3).then(r => printTime('result:', r))// 输出结果result:1 index:1 args:[object Object],3result:2 index:2 args:[object Object],3result:3 index:3 args:[object Object],32018-3-9 16:43:44 result: 3

可以看到

  1. callback 函数,拿到的参数是,上次的执行结果, 索引值,传入的其他参数
  2. 三个返回Promise的函数是依次执行的
  3. 执行完毕后,我们输出了最后的时间和最后的执行结果
    那么,就达到了Promise的顺序执行
    最后奉上完整代码和下载地址
/** * 转换为Promise集合 * @param {Promise的集合或者之后后返回promise的函数集合} promises  * @param {附加参数} args  */function toPromise(promises, ...args) {    return promises.map(p => typeof p === 'function' ? p(...args) : p)}/** * 返回Promise.all * @param {Promise的集合或者之后后返回promise的函数集合} promises  * @param {附加参数} args  */function all(promises, ...args) {    return Promise.all(toPromise(promises, ...args))}/** * 返回Promise.race * @param {Promise的集合或者之后后返回promise的函数集合} promises  * @param {附加参数} args  */function race(promises, ...args) {    return Promise.race(toPromise(promises, ...args))}/** * 顺序执行Promise,并返回结果 * @param {返回promise的函数集合} promises  * @param {每一步的回调函数,非异步,可以考虑后期支持} cb  * @param {附加参数} args  */function sequence(promises, cb, ...args) {    const p = Promise.resolve(),        len = promises.length    if (len <= 0) {        return p    }    let i = 0    //如果cb不是函数    if (typeof cb !== 'function') {        cb = null        args = [cb, ...args]    }    function callBack(...params) {        return p.then(r => {            return promises[i](r, ...params)        }).then(r => {            ++i            cb && cb(r, i, ...params)            return i > len - 1 ? Promise.resolve(r) : callBack(...params)        })    }    return callBack(...args)}/** * 顺序执行Promise,并返回结果, 需要主动执行sequence(promises)(6) * @param {返回promise的函数集合} promises  * @param {附加参数} args  */function delaySequence(promises, cb, ...args) {    return function (..._args) {        return sequence(promises, cb, ...[...args, ..._args])    }}const plus = {    race,    all,    sequence,    delaySequence}module.exports = plus

这里我应用到了自己编写的 FlowMongoActivity.js,用来顺序执行mongo的操作命令.

这里再贴一份 30-seconds-of-code 里面的runPromisesInSeries

const runPromisesInSeries = ps => ps.reduce((p, next) => p.then(next), Promise.resolve());
版权声明

本文仅代表作者观点,不代表百度立场。
本文系作者授权百度百家发表,未经许可,不得转载。

热门文章
  • 机房智能化温湿度解决方式之POE供电以太网温湿度传感器

    机房智能化温湿度解决方式之POE供电以太网温湿度传感器
    机房智能化温湿度解决方式之POE供电以太网温湿度传感器 北京盈创力和电子科技有限公司 智能型TCP网口温湿度记录仪 北京IP网络温湿度记录仪厂家,北京盈创力和 北京智能型TCP网口温湿度记录仪IP网络温湿度记录仪是一种新型的基于TCP/IP协议双绞线以太网标准温湿度采集模块,利用它可以实现现场温度值、相对湿度值的采集,同时利用其自身的RJ45通信接口可以方便地和机房监控主机或交换机集线器进行联网。 工作于-40℃~85℃工业级带...
  • Sequential Monte Carlo Methods (SMC) 序列蒙特卡洛/粒子滤波/Bootstrap Filtering

    Sequential Monte Carlo Methods (SMC) 序列蒙特卡洛/粒子滤波/Bootstrap Filtering
    Problem Statement 我们考虑一个具有马尔可夫性质、非线性、非高斯的状态空间模型(State Space Model):对于一个时间序列上的观测结果{yt,t∈N}\\{ y_t , t \\in N \\}{yt​,t∈N},我们认为每个观测结果yty_tyt​的生成依赖于一个无法直接观察的隐变量xt∈{xt,t∈N}x_t \\in \\{x_t , t \\in N \\}xt​∈{xt​,t∈N},即:p(...
  • HTTP状态保持的原理

    HTTP状态保持的原理
    a)在用户登录之后,浏览器返回响应的时候会在响应中添加上cookieb)浏览器接收到cookie之后会自动保存c)当用户再次请求同一服务器中的其他网页的时候,浏览器会自动带上之前保存的cookied)服务接收到请求之后可以请 request 对象中取到cookie 判断当前用户是否登录  Http是无状态的,就是连接时数据互通,关闭后...
  • Hive 系统函数及示例

    Hive 系统函数及示例
    查看所有系统函数 show functions; 函数分类 内置函数【系统函数】 数学函数: floor、round、ceil、cos、log2等 字符串函数: length、reverse、trim、lower、get_json_object、repeat等 收集函数: size 转换函数: cast 日期函数: year、month、datediff、date、date_add等 条件函数: coalesce、case…w...
  • CSRF的原理和防范措施

    CSRF的原理和防范措施
    a)攻击原理:i.用户C访问正常网站A时进行登录,浏览器保存A的cookieii.用户C再访问攻击网站B,网站B上有某个隐藏的链接或者图片标签会自动请求网站A的URL地址,例如表单提交,传指定的参数iii.而攻击网站B在访问网站A的时候,浏览器会自动带上网站A的cookieiv.所以网站A在接收到请求之后可判断当前用户是登录状态,所以...
标签列表