Created
May 17, 2012 09:12
-
-
Save leizongmin/2717618 to your computer and use it in GitHub Desktop.
JavaScript简单异步执行
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* 使用方法: | |
* step(function (data, next) { | |
* // step 1, do somethings... | |
* next(null, data); | |
* }, function (data, next) { | |
* // step 2, do somethings... | |
* next(null, data); | |
* }, function (err, data) { | |
* // callback | |
* }); | |
* 说明: | |
* 前N-1个参数为要顺序执行的函数,接收两个参数: data和next,参数data可用于传递结果给下个执行的函数,参数next用于执行下一个函数 | |
* 最后一个参数为所有步骤执行完毕(或中途出错)后的回调函数,接收两个参数:err和data,如果中途出错,则err不等于null | |
*/ | |
function step () { | |
var fn = []; | |
for (var i = 0, len = arguments.length - 1; i < len; i++) { | |
fn.push(arguments[i]); | |
} | |
var callback = arguments[i]; | |
var i = -1; | |
var next = function (err, data) { | |
if (err) { | |
return callback(err, data); | |
} | |
i++; | |
if (typeof fn[i] === 'function') { | |
try { | |
return fn[i](data, next); | |
} | |
catch (err) { | |
return callback(err, data); | |
} | |
} | |
else { | |
return callback(null, data); | |
} | |
}; | |
next(null, {}); | |
}; | |
// 例1: | |
step( | |
function (data, next) { | |
data.num1 = Math.random(); | |
setTimeout(function () { | |
next(null, data); | |
}, 50); | |
}, | |
function (data, next) { | |
data.num2 = Math.random(); | |
setTimeout(function () { | |
next(null, data); | |
}, 20); | |
}, | |
function (data, next) { | |
data.num3 = Math.random(); | |
setTimeout(function () { | |
next(null, data); | |
}, 100); | |
}, | |
function (err, data) { | |
console.log(err, data); | |
} | |
); | |
// 例2(中途出错): | |
step( | |
function (data, next) { | |
data.num1 = Math.random(); | |
next(null, data); | |
}, | |
function (data, next) { | |
data.num2 = Math.random(); | |
next(null, abcd); | |
}, | |
function (data, next) { | |
data.num3 = Math.random(); | |
next(null, data); | |
}, | |
function (err, data) { | |
console.log(err, data); | |
} | |
); | |
// 例3(Node.js异步方式读取目录下文件的属性): | |
var fs = require('fs'); | |
fs.readdir('.', function (err, files) { | |
if (err) | |
throw err; | |
var readFileStat = function (file) { | |
return function (data, next) { | |
fs.stat(file, function (err, stats) { | |
if (err) | |
return next(err); | |
data[file] = stats; | |
next(null, data); | |
}); | |
}; | |
}; | |
var fn = []; | |
for (var i = 0, len = files.length; i < len; i++) | |
fn.push(readFileStat(files[i])); | |
fn.push(function (err, data) { | |
if (err) | |
throw err; | |
console.log(data); | |
}); | |
step.apply(null, fn); | |
}); | |
// 例4(Node.js异步方式遍历目录): | |
var fs = require('fs'); | |
var path = require('path'); | |
function expand (dir, callback) { | |
try { | |
fs.readdir(dir, function (err, files) { | |
if (err) | |
return callback(err); | |
var fn = []; | |
for (var i = 0, len = files.length; i < len; i++) | |
fn.push(_expandChild(path.join(dir, files[i]))); | |
fn.push(function (err, data) { | |
if (err) | |
return callback(err); | |
callback(null, data.files || []); | |
}); | |
step.apply(null, fn); | |
}); | |
} | |
catch (err) { | |
return callback(err); | |
} | |
} | |
function _expandChild (dir) { | |
return function (data, next) { | |
if (!Array.isArray(data.files)) | |
data.files = []; | |
data.files.push(dir); | |
fs.stat(dir, function (err, stats) { | |
if (stats.isDirectory()) { | |
console.log('[dir] ' + dir); | |
expand(dir, function (err, files) { | |
if (err) | |
return next(err); | |
data.files = files.concat(data.files); | |
next(null, data); | |
}); | |
} | |
else { | |
console.log('[File] ' + dir); | |
next(null, data); | |
} | |
}); | |
}; | |
} | |
expand(path.resolve('../'), function (err, files) { | |
if (err) | |
console.log(err.stack); | |
console.log(files); | |
}); | |
setInterval(function () { | |
console.log(' Time: ' + new Date()); | |
}, 50); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment