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

[[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 对象,而且代码行数也略多一点。无论怎样我最重还是选了同事的方案。。毕竟可读性第一嘛。

一次Promise 实践:异步任务的分组调度的更多相关文章

  1. Angular JS 学习笔记(自定义服务:factory,Promise 模式异步请求查询:$http,过滤器用法filter,指令:directive)

    刚学没多久,作了一个小项目APP,微信企业号开发与微信服务号的开发,使用的是AngularJS开发,目前项目1.0版本已经完结,但是项目纯粹为了赶工,并没有发挥AngularJS的最大作用,这几天项目 ...

  2. Promise和异步编程

    前面的话 JS有很多强大的功能,其中一个是它可以轻松地搞定异步编程.作为一门为Web而生的语言,它从一开始就需要能够响应异步的用户交互,如点击和按键操作等.Node.js用回调函数代替了事件,使异步编 ...

  3. Promise与异步

    不知道promise,大家现在用了吗?如果还不了解的话,今天就来对了-基础的了解起来- 正文从这开始- 接触过promise的的都知道它的应用场景和用途,Promise可以用来避免异步操作函数里的嵌套 ...

  4. Promise实践

    一.概念 Promise是异步编程的解决方案之一,与事件驱动+回调函数并列. Promise是专门为异步编程设计的封闭的一次性用品,封闭体现在只有异步操作的结果能改变其状态,其他任何操作都不能改变其状 ...

  5. ES6 Promise 让异步函数顺序执行

    应用 ES6 的 内置对象 Promise, 让异步函数 按顺序执行的例子 如下: 上边 是四个用Promise 处理过的 异步执行的函数: fn1.fn2.fn3.fn4 下面,让其按顺序执行 如下 ...

  6. Promise对象 异步编程

    Promise 的含义 Promise 是异步编程的一种解决方案,比传统的解决方案——回调函数和事件——更合理和更强大.所谓Promise,简单说就是一个容器,里面保存着某个未来才会结束的事件(通常是 ...

  7. Node.js用ES6原生Promise对异步函数进行封装

    Promise的概念 Promise 对象用于异步(asynchronous)计算..一个Promise对象代表着一个还未完成,但预期将来会完成的操作. Promise的几种状态: pending:初 ...

  8. jquery的promise实践--连续加载图片

    在javascript设计模式实践之代理模式--图片预加载中用代理模式实现了图片预加载功能. 现在就更进一步,完成一个能够一张一张的连续图片加载的功能. 功能: 1.一张一张加载图片. 2.加载错误, ...

  9. jquery.Deferred promise解决异步回调

    我们先来看一下编写AJAX编码经常遇到的几个问题: 1.由于AJAX是异步的,所有依赖AJAX返回结果的代码必需写在AJAX回调函数中.这就不可避免地形成了嵌套,ajax等异步操作越多,嵌套层次就会越 ...

随机推荐

  1. BZOJ 1090: [SCOI2003]字符串折叠

    Sol 区间DP. 转移很简单,枚举会形成的断长转移就行,话说上一题我就跟这个是差不多的思路,转移改了改,然后死活过不了... 同样都是SCOI的题...相差4年... Code /********* ...

  2. linux系统下获取IP,MAC,子网掩码,网关

    获取IP和子网掩码 int getLocalInfo(char IP[],char Mask[]) { int fd; int interfaceNum = 0; struct ifreq buf[1 ...

  3. linux awk, xargs

    awk , 很赞的教程:http://coolshell.cn/articles/9070.html xargs, http://blog.csdn.net/andy572633/article/de ...

  4. centos 6.5 git 服务器的配置(入门级)

    参考:https://www.digitalocean.com/community/tutorials/how-to-set-up-a-private-git-server-on-a-vps http ...

  5. svn: E155004 'XX' is already locked

    Error:svn: E155004: Run 'svn cleanup' to remove locks (type 'svn help cleanup' for details)svn: E155 ...

  6. ubuntu dhcp修改ip地址

    sudo vim /var/lib/dhcp/dhclient.eth0.leases 把里边的fixed-address都改成你想要的ip. 然后执行 sudo ifdown eth0 && ...

  7. jq鼠标隐藏显示的方法

    <div style="width:300px; float:left;">        <div onmouseover="testOnmouseO ...

  8. 【转】ArrayList其实就那么一回事儿之源码浅析

    转自:http://www.cnblogs.com/dongying/p/4013271.html?utm_source=tuicool&utm_medium=referral ArrayLi ...

  9. 79 两个整数集合A和B,求其交集

    [本文链接] http://www.cnblogs.com/hellogiser/p/ab-intersect.html [题目] 两个整数集合A和B,求其交集. [分析]   1. 读取整数集合A中 ...

  10. Java for LeetCode 225 Implement Stack using Queues

    Implement the following operations of a stack using queues. push(x) -- Push element x onto stack. po ...