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
更多内容可以参考官网:http://caolan.github.io/nimble/
本文转自:Node.js 模块之Nimble流程控制