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

[[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. 12 哈希表相关类——Live555源码阅读(一)基本组件类

    12 哈希表相关类--Live555源码阅读(一)基本组件类 这是Live555源码阅读的第一部分,包括了时间类,延时队列类,处理程序描述类,哈希表类这四个大类. 本文由乌合之众 lym瞎编,欢迎转载 ...

  2. c++ SOA Axis2c 编译安装

    Axis2C 安装过程 1设置环境变量 export AXIS2C_HOME=/usr/local/axis2c 2.下载源码包解压编译安装 cd axis2c-src-1.6.0 ./configu ...

  3. 如何解决phpcms后台验证码不显示的问题

    方法一: 主要在于是否开启gd库 查看办法 找到php.ini文件 搜索extension=php_gd2.dll这段代码(windows) 然后把前面的;符号去掉即可. centOS6.5中可能需要 ...

  4. phpcms分页用法简介

    PHPCMS分页的用法 前面需要有引用的list,代码如下: {pc:content action="lists" catid="11" order=" ...

  5. Appium+Robotframework实现Android应用的自动化测试-5:RIDE中AppiumLibrary的配置

    可能很多朋友已经迫不及待的想要用RobotFramework+AppiumLibrary来写Android App的测试脚本了,那我们也废话少说,直接开始. 首先打开RIDE,这是编写RobotFra ...

  6. android studio Error:java.lang.OutOfMemoryError: GC overhead limit exceeded

    android studio Error:java.lang.OutOfMemoryError: GC overhead limit exceeded 在app下的build.gradle中找到and ...

  7. ubuntu14.04和win7共享文件夹

    环境:vmware12 问题:安装了vmware-tools,但是在/mnt/hgfs下面看不到共享的文件夹. 按照网上的一些经验和教程使用如下命令: mount -t vmhgfs .host:/ ...

  8. MongoDB 3.0 用户创建

    摘要: MongoDB 3.0 安全权限访问控制,在添加用户上面3.0版本和之前的版本有很大的区别,这里就说明下3.0的添加用户的方法. 环境.测试: 在安装MongoDB之后,先关闭auth认证,进 ...

  9. 全能直播王PC版-0707-full_codecs

    全能直播王是一款高清流畅的全平台的电视直播应用,让您随时随地看高清电视直播. [全能特色] 1. 收录全国1400多个直播频道,包括湖南卫视.江苏卫视.浙江卫视等热门频道. 2. 频道多线路自动选择, ...

  10. WebRequest 获取网页乱码

    问题:在用WebRequest获取网页源码时得到的源码是乱码. 原因:1,编码不对 解决办法:设置对应编码 WebRequest request = WebRequest.Create(Url);We ...