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

[[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 2438: [中山市选2011]杀人游戏

    Description 给你一个有向图,求至少询问多少次能够得到全部点的信息. Sol Tarjan + 强连通分量缩点 + 判断. 先缩点,如果我们知道了强连通分量里的任意一个点,我们就可以知道这些 ...

  2. Eclipse中项目红叉但找不到错误解决方法

    首先windows-show view-problems 根据地址查找错误 若提示: Description    Resource    Path    Location    TypeJava c ...

  3. phpcms新闻轮播图实现

    首页如果有新闻的轮播图,点击图片可以进入相关的新闻.因为已经使用外部js轮播插件,所以想不修改插件进行轮播 我用的js插件是yx-rotaion插件,配合phpcms的get工具箱对新闻进行读取并抽取 ...

  4. 在本地计算机无法启动MYSQL服务错误1067进程意外终止

    在本地计算机无法启动MYSQL服务错误1067进程意外终止 这种情况一般是my.ini文件配置出错了, 你可以删除系统目录下的my.ini文件, 把下面的内容重新写入my.ini文件试试, 要适当地改 ...

  5. 用dygraphs图表分析xdebug的trace结果

    2015年12月1日 19:44:23 推荐这一篇用百度的ECharts图表工具 本文用到的js图表库: dygraphs 注: 测试数据量 19108个数据点, 最好将数据的量级调小, 这样渲染会很 ...

  6. Java for LeetCode 210 Course Schedule II

    There are a total of n courses you have to take, labeled from 0 to n - 1. Some courses may have prer ...

  7. c#操作时间

    本年还剩下多少天 private string GetEndTime() { DateTime dt = DateTime.Now; DateTime startYear = DateTime.Now ...

  8. 迭代器iterator

    现在接着上篇的,写一来标识vector 的元素的对象迭代器iterator: 还是通过具体代码举例: 下面我讲了一个我暑期团队的故事哦~~: #include<iostream> #inc ...

  9. 【leetcode】Reverse Linked List II (middle)

    Reverse a linked list from position m to n. Do it in-place and in one-pass. For example:Given 1-> ...

  10. 【C语言】文件

    fopen fseek fprintf fclose 先用这几个函数