zoukankan      html  css  js  c++  java
  • 一次Promise 实践:异步任务的分组调度

    起因是在工作中遇到一个问题,可以用一个二维数组简单描述:

    [[1,2,3],[4,5,6],[7,8,9]]

    这里每个数字都代表“一个异步计算任务”, 每个子数组把1个或多个计算任务划分成组,要求是:每组内的计算任务并行执行,但是各个组间要顺序执行。具体说来就是先执行1,2,3 等获得全部的结果以后再执行4,5,6以此类推。最后返回的结果跟执行顺序相同。

    经过了大概半小时的尝试与思考,我写出了一个版本:

    function dispatch(groups) {
        var result = Promise.resolve([])
        groups.forEach(function (group) {
            result = result.then(function (prevVal) {
    
                var ps = []
                group.forEach(function (task) {
                    ps.push(Promise.resolve(task))
                })
    
                return Promise.all(ps).then(function (r) {
                    prevVal.push(r)
                    return prevVal
                })
            })
        })
        return result
    }

    调用方法:

    dispatch([[1,2,3],[4,5,6],[7,8,9]]).then(function (result) {
        console.log(result) //[[1,2,3],[4,5,6],[7,8,9]]
    });

    基本思路就是,从第一组开始,对其中的所有异步任务求值,求值成功后再开始第二组...最后当遍历完全部组后,返回结果。

    可以简单描述为:resolve([1,2,3]).then([4,5,6]).then([7,8,9])

    思路看似简单直观,但是如何动态的创建then 链条确实花费了我不少脑筋,写完代码后也对promise 有了更深刻的理解。

    写完代码后我兴高采烈地拿给同事看,同事说我这个写得太复杂不容易看懂,他能写出一个更简单直观的递归方案,大概十分钟后他拿出代码:

    function dispatch(groups) {
        var results = []
        return (function () {
            var fun = arguments.callee
                , group = groups.shift()
            if (!group) {
                return Promise.resolve(results)
            }
    
            var promises = []
            group.forEach(function (task) {
                promises.push(
                    Promise.resolve(task)
                )
            })
    
            return Promise.all(promises).then(function (rets) {
                results.push(rets)
                return fun()
            })
        }())
    } 

    貌似真的比我那个要直观,但是貌似这个方案要比我那个多创建一个Promise 对象,而且代码行数也略多一点。无论怎样我最重还是选了同事的方案。。毕竟可读性第一嘛。

  • 相关阅读:
    状压dp大总结1 [洛谷]
    集训日记(暑期第二周)【真正的集训,真正的考试】
    集训日记(暑期第一周)【6.22始】
    集训模拟赛3【啥也不会的一天】
    P2194 HXY烧情侣【Tarjan】
    6.28-集训模拟赛2【水爆但有进步的半天】
    Linux基础管道管理
    Linux基础进程管理优先级
    awk文本处理
    sed流编辑器
  • 原文地址:https://www.cnblogs.com/agentgamer/p/4471974.html
Copyright © 2011-2022 走看看