NodeJS异步的特性有时候会导致程序非常的难看,回调一层套着一层,这个时候就要用流程控制模块来控制究竟是同步还是异步了。

Nimble是一个轻量、可移植的函数式流程控制模块。经过最小化和压缩后只有837字节,可以运行在Node.js中,也可以用在各种浏览器中。它整合了underscore和async一些最实用的功能,并且API更简单。

nimble有两个流程控制函数,_.parallel和_.series。顾名思义,我们要用的是第二个,可以让一组函数串行执行的_.series。下面这个命令是用来安装Nimble的:

npm install nimble

如果用.series调度执行上面那个解方程的函数,代码应该是这样的:

...
var flow = require('nimble');
(function calculate(i) {if(i === l-1) {variables[i] = res[i];process.exit();}else {flow.series([function (callback) {calculateTail(res[i],res[i+1],function(tail) {variables[i] = tail;callback();});},function (callback) {calculateHead(res[i],res[i+1],function(head) {res[i+1] = head;callback();});},function(callback){calculate(i+1);}]);}
})(0);
...

.series数组参数中的函数会挨个执行,只是我们的calculateTail和calculateHead都被包在了另一个函数中。尽管这个用流程控制实现的版本代码更多,但通常可读性和可维护性要强一些。

更多实例:

串行执行(非异步):

var flow = require('nimble');flow.series([function (callback){setTimeout(function(){console.log('I execute first.');callback();newfunc();}, 1000)},function (callback){setTimeout(function(){console.log('I execute next.');callback();}, 2000)},function (callback){setTimeout(function(){console.log('I execute last.');callback();}, 100)}
]);

并行执行(异步):

var flow = require('nimble');flow.parallel([function (callback) {setTimeout(function () {console.log('one');callback();}, 25);},function (callback) {setTimeout(function () {console.log('two');callback();}, 0);}
]);

串并行兼顾(流程控制):

var flow = require('nimble');
var exec = require('child_process').exec;function downloadNodeVersion(version, destination, callback)
{var url      = 'http://nodejs.org/dist/node-v' + version + '.tar.gz';var filepath = destination + '/' + version + '.tgz';exec('curl ' + url + ' > ' + filepath, callback);
}flow.series
([function(callback){flow.parallel([function(callback){console.log('Downloading Node v0.4.6...');downloadNodeVersion('0.4.6', '/tmp', callback);},function(callback){console.log('Downloading Node v0.4.7...');downloadNodeVersion('0.4.7', '/tmp', callback);}], callback);},function(callback){console.log('Creating archive of downloading files...');exec('tar cvf node_distros.tar /tmp/0.4.6.tgz /tmp/0.4.7.tgz',function(error, stdout, stderr){console.log('All Done!');callback();})}
]);

这个稍微解释一下:先异步下载文件,文件下载完成后,再把所有文件打包。

nimble.min.js

(function(a){var b=Object.keys||function(a){var b=[];for(var c in a)a.hasOwnProperty(c)&&b.push(c);return b};var c=function(a,b){var c=Array.prototype[a];return function(d,e,f){var g=d?d[a]:0;return g&&g===c?g.call(d,e,f):b(d,e,f)}};var d=c("forEach",function(a,c){var d=a instanceof Object;var e=d?b(a):a||[];for(var f=0,g=e.length;f<g;f++){var h=d?e[f]:f;c(a[h],h,a)}});var e=function(a,c,e){var f=a.length||b(a).length;if(!f)return e();var g=0;d(a,function(){var a=function(a){a?(e(a),e=function(){}):++g===f&&e()};var b=Array.prototype.slice.call(arguments);c.length?(b=b.slice(0,c.length-1),b[c.length-1]=a):b.push(a),c.apply(this,b)})};var f=function(a,c,d){var e=b(a);if(!e.length)return d();var f=0;var g=function(){var b=e[f];var h=[a[b],b,a].slice(0,c.length-1);h[c.length-1]=function(a){a?(d(a),d=function(){}):++f===e.length?d():g()},c.apply(this,h)};g()};var g=c("map",function(a,b){var c=[];d(a,function(a,d,e){c[c.length]=b(a,d,e)});return c});var h=function(a){return function(b,c,d){var e=[];a(b,function(a,b,d,f){var g=function(a,b){e[e.length]=b,f(a)};var h=[a,b,d];c.length?(h=h.slice(0,c.length-1),h[c.length-1]=g):h.push(g),c.apply(this,h)},function(a){d(a,e)})}};var i=c("filter",function(a,b,c){var e=[];d(a,function(a,c,d){b(a,c,d)&&(e[e.length]=a)});return e});var j=function(a,b,c){var d=[];e(a,function(a,c,e,f){var g=function(b,c){c&&(d[d.length]=a),f(b)};var h=[a,c,e];b.length?(h=h.slice(0,b.length-1),h[b.length-1]=g):h.push(g),b.apply(this,h)},function(a){c(a,d)})};var k=c("reduce",function(a,b,c){d(a,function(a,d,e){c=b(c,a,d,e)});return c});var l=function(a,b,c,d){f(a,function(a,d,e,f){var g=function(a,b){c=b,f(a)};var h=[c,a,d,e];b.length?(h=h.slice(0,b.length-1),h[b.length-1]=g):h.push(g),b.apply(this,h)},function(a){d(a,c)})};a.each=function(a,b,c){return(c?e:d)(a,b,c)},a.map=function(a,b,c){return(c?h(e):g)(a,b,c)},a.filter=function(a,b,c){return(c?j:i)(a,b,c)},a.reduce=function(a,b,c,d){return(d?l:k)(a,b,c,d)},a.parallel=function(a,b){var c=new a.constructor;e(a,function(a,b,d){a(function(a){var e=Array.prototype.slice.call(arguments,1);c[b]=e.length<=1?e[0]:e,d(a)})},function(a){(b||function(){})(a,c)})},a.series=function(a,b){var c=new a.constructor;f(a,function(a,b,d){a(function(a,e){var f=Array.prototype.slice.call(arguments,1);c[b]=f.length<=1?f[0]:f,d(a)})},function(a){(b||function(){})(a,c)})}})(typeof exports==="undefined"?this._=this._||{}:exports)

更多内容可以参考官网:http://caolan.github.io/nimble/

本文转自:Node.js 模块之Nimble流程控制

Node.js 模块之Nimble流程控制相关推荐

  1. node 大写_大写Node.js模块

    node 大写 Today, let's see a third party module that helps us in working with upper-case letters witho ...

  2. 编写原生的Node.js模块

    通常,我们开发原生Node.js模块包括但不仅限于以下原因: 对性能有比较苛刻要求的应用.尽管Node.js得益于libuv,在异步I/O操作很有优势,但遇到数字计算时并不是一个很好的选择. 使用更加 ...

  3. Node.js「一」—— Node.js 简介 / Node.js 模块 / 包 与 NPM

    本文为 Node.js 系列笔记第一篇.文章参考:nodejs 教程 -- 大地:<深入浅出 Node.js>:阮一峰 nodejs 博客 文章目录 一.Node 简介 1. 简单介绍 2 ...

  4. (8)Node.js 模块介绍

    一.Node.js模块介绍 模块(包)是 Node.js 中具有特定功能的对象. 二.web浏览器端和Node端的对比图 我们通过如上图可以看到,再web浏览器端的基本语法,再Node端也能使用,但是 ...

  5. 不再为 Node.js 模块自动引入 Polyfills

    在早期,webpack 的目的是为了让大多数的 Node.js 模块运行在浏览器中,但如今模块的格局已经发生了变化,现在许多模块主要是为前端而编写.webpack <= 4 的版本中提供了许多 ...

  6. node.js 模块_如何创建Node JS可重用模块

    node.js 模块 In my previous post, we have discussed about "How to export and import a Node JS Mod ...

  7. Node.js---02、node.js 模块加载机制

    2019独角兽企业重金招聘Python工程师标准>>> node.js模块分为自定义模块.扩展模块和核心模块.所有模块的加载都是通过关键字require()实现. 1.自定义模块的加 ...

  8. node mocha_如何使用Mocha和Assert测试Node.js模块

    node mocha The author selected the Open Internet/Free Speech Fund to receive a donation as part of t ...

  9. html怎么调用node.js,javascript – 在HTML中使用Node.js模块

    我有以下Node.js项目(这是我的问题的最小工作示例): module1.js: module.exports = function() { return "this is module1 ...

最新文章

  1. 查找无序数组中第K大的数
  2. webserver通信过程
  3. fastai 核心部件
  4. 3.1 Adapter(适配器)
  5. linux 提取ko文件,Linux获取so/ko文件版本号教程
  6. std::future ---C++17 多线程
  7. unity3d 2D版本见缝插针demo
  8. Pentium 4处理器架构/微架构/流水线 (8) - NetBurst执行核详解 - 指令时延与吞吐量
  9. 测试计划与测试方案的区别
  10. POJ 3037 SPFA
  11. js string函数之slice,indexOf,split联合获取参数
  12. 【Lingo 18.0及其安装教程】
  13. dev-cpp linux,QT4+Devcpp开发环境搭建(参照网上资料整理)
  14. mysql批量导出工具_sql数据库批量导出|
  15. 简单的钓鱼网站的制作
  16. html submit修改名称,HTML Input Submit name用法及代码示例
  17. SpringBoot之SpringData JPA的基本使用
  18. php中的implode,php里implode是什么意思
  19. SAP产品成本计算流程
  20. 云计算高级运维第一阶段项目实战:在局域网中使用 awl 伪装 MAC 地址进行多线程 SYN 洪水攻击

热门文章

  1. Product of Three Numbers(CF-1294C)
  2. Cow Line(洛谷-P3014)
  3. 信息学奥赛一本通C++语言——1043:整数大小比较
  4. 38 CO配置-控制-产品成本控制-成本对象控制-实际成本核算/物料分类帐-分配材料分类帐类型给评估区域
  5. 20 FI配置-财务会计-定义税务科目
  6. java代码鸟飞_180行原生js代码实现简易版飞行的小鸟游戏
  7. cad插件加载bplot成功用不了_新手入门,学习CAD必须掌握,教你使用标注命令,绘图效率翻一倍...
  8. BiSeNet V2论文及源码
  9. linux内核那些事之buddy(慢速申请内存__alloc_pages_slowpath)(5)
  10. OpenCV防止数据溢出saturate_cast