Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
6978469
add *package.json* so people can get the dependencies conveniently.
alsotang Sep 18, 2012
fc49798
添加了更多注释
alsotang Sep 18, 2012
bfcb64a
del undefined x at line 14
termux-io Aug 31, 2013
a8091dd
Merge pull request #1 from palmtoy/master
alsotang Sep 1, 2013
d2d3455
'update1'
bsspirit Sep 12, 2013
d9c26e6
update1
bsspirit Sep 12, 2013
61b7cf5
remove_idea
bsspirit Sep 12, 2013
1d67241
'ignore'
bsspirit Sep 12, 2013
292c3a1
reject
bsspirit Sep 12, 2013
85251c8
'reduce'
bsspirit Sep 12, 2013
46a6ba2
'detect'
bsspirit Sep 12, 2013
51fba3d
'some'
bsspirit Sep 12, 2013
74caddf
'every'
bsspirit Sep 12, 2013
04c808d
'series'
bsspirit Sep 12, 2013
09a642d
'paralel'
bsspirit Sep 12, 2013
5ea2845
'whilist,until'
bsspirit Sep 12, 2013
3f239bc
'forever'
bsspirit Sep 12, 2013
1373c22
'waterfall'
bsspirit Sep 12, 2013
d09c18d
'apply'
bsspirit Sep 12, 2013
4ed25b5
'nextTick'
bsspirit Sep 12, 2013
2e5e596
'times_timesSeries'
bsspirit Sep 12, 2013
6bb157b
'iterator'
bsspirit Sep 12, 2013
d55aefb
'auto'
bsspirit Sep 12, 2013
9863380
'queue'
bsspirit Sep 12, 2013
681ddc1
'cargo'
bsspirit Sep 12, 2013
2bab3d9
'applyEach'
bsspirit Sep 13, 2013
e07c78d
'utils.js'
bsspirit Sep 13, 2013
65a785d
'mapLimit'
bsspirit Sep 13, 2013
023eadf
'detail'
bsspirit Sep 13, 2013
1f5b0a1
'update'
bsspirit Sep 13, 2013
851aa84
Update README.md
bsspirit Aug 14, 2014
c4bea11
Update README.md
bsspirit Aug 14, 2014
12eaf54
Update README.md
bsspirit Aug 14, 2014
8d8acff
fix typo
gejiawen Nov 2, 2015
236677b
Merge pull request #2 from gejiawen/master
alsotang Nov 2, 2015
49bbe2e
fix a misleading typo in some.js
ifivebig Aug 5, 2016
0d30c3e
fix a misleading typo in every.js
ifivebig Aug 5, 2016
557035d
Merge pull request #4 from ifivebig/patch-2
alsotang Aug 5, 2016
6b7a652
Merge pull request #3 from ifivebig/patch-1
alsotang Aug 5, 2016
0ea2a78
auto.js中参数错误导致无法正常运行
Dec 19, 2016
3522899
Merge pull request #5 from For-me/master
alsotang Dec 19, 2016
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
node_modules/
.idea
51 changes: 50 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,53 @@
async_demo
==========

A demo for async
A demo for async.

+ http://blog.fens.me/nodejs-async/
+ http://blog.fens.me/nodejs-async-timer/

INSTALL
===========================

```{bash}
git clone https://github.com/bsspirit/async_demo.git
cd async_demo
```

Change Log
===================================

参考async@0.2.9版本的规范

https://github.com/caolan/async

1. forEach.js改名为each.js
2. each.js文件中的async.forEach,改为async.each
3. map.js增加mapLimit函数
4. filter_reject.js对注释补充
5. filter_reject.js增加rejectSeries函数
6. reduce.js增加注释
7. detect.js增加注释
8. sortBy.js增加注释
9. some.js对注释补充
10. every.js对注释补充和修改
11. series.js调整注释格式
12. parallel.js调整注释格式
13. parallel.js增加parallelLimit函数
14. whilist_until.js调整注释格式
15. whilist_until.js增加doWhilst函数
16. whilist_until.js增加doUntil函数
17. whilist_until.js增加forever函数
18. waterfall.js调整注释格式
19. 增加compose.js文件
20. apply.js补充注释并增加一个实例
21. 修改nextTick.js实例
22. 增加times.js文件,包括times和timesSeries函数
23. 修改iterator.js实例
24. 修正auto.js关于第二个实例的错误解释
25. 修改queue.js实例和注释
26. 修改cargo.js文件
27. 增加applyEach.js文件
28. 修改utils.js实例和注释


31 changes: 24 additions & 7 deletions apply.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,24 +4,41 @@ var t = require('./t');
var log = t.log;

/**
* async.apply是一个非常好用的函数,可以让我们给一个函数预绑定多个参数并生成一个可直接调用的新函数,简化代码。
* apply是一个非常好用的函数,可以让我们给一个函数预绑定多个参数并生成一个可直接调用的新函数,简化代码。
*
* function(callback) { t.inc(3, callback); }
* 等价于:
* async.apply(t.inc, 3);
*/
// apply(function, arguments..)

/**
* 通过名字绑定函数t.inc, t.fire,作为新函数给parallel调用
*/
//1.1
async.parallel([
async.apply(t.inc, 3),
async.apply(t.fire, 100)
], function (err, results) {
log('err: ', err);
log('results: ', results);
log('1.1 err: ', err);
log('1.1 results: ', results);
});
//58.605> 1.1 err: null
//58.613> 1.1 results: [ 4, 100 ]

// 预设参数
var x = async.apply(t.inc, 1);
x(function(err, n){
console.log('1.inc: ' + n);
/**
* 构造一个加法函数,通过apply简化代码
*/
//1.2
function inc(a,b,callback,timeout){
var timeout = timeout || 200;
t.wait(200);
setTimeout(function() {
callback(null, a+b);
}, timeout);
}
var fn = async.apply(inc, 1, 2);
fn(function(err, n){
log('1.2 inc: ' + n);
});
//58.616> 1.2 inc: 3
79 changes: 79 additions & 0 deletions applyEach.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
var async = require('async');
var t = require('./t');
var log = t.log;

/**
* applyEach,可以实现给一数组中每个函数传相同参数,通过callback返回。
* 如果只传第一个参数,将返回一个函数对象,我可以传参调用。
*/
// applyEach(fns, args..., callback)

/**
* 异步执行,给数组中的函数,他们有相同的参数。
*/
//1.1
async.applyEach([
function (name,cb) {
setTimeout(function () {
log("1.1 handler: " + name + " A");
cb(null, name);
}, 500);
}, function (name,cb) {
setTimeout(function () {
log("1.1 handler: " + name + " B");
cb(null, name);
}, 150);
}
], 'Hello', function (err) {
log('1.1 err: ', err);
});
//06.739> 1.1 handler: Hello B
//07.079> 1.1 handler: Hello A
//07.080> 1.1 err: null

/**
* 异步执行,当只设置第一参数后,得到函数对象,再传参调用这个函数。
*/
//1.2
var fn = async.applyEach([
function (name,cb) {
setTimeout(function () {
log("1.2 handler: " + name + " A");
}, 500);
}, function (name,cb) {
setTimeout(function () {
log("1.2 handler: " + name + " B");
}, 150);
}
]);
fn("simgle",function(err){
log('err: ',err);
});
//29.351> 1.2 handler: simgle B
//29.688> 1.2 handler: simgle A

/**
* applyEachSeries与applyEach唯一不同的是,数组的函数同步执行。
*/
//applyEachSeries(arr, args..., callback)
//1.3
async.applyEachSeries([
function (name,cb) {
setTimeout(function () {
log("1.3 handler: " + name + " A");
cb(null, name);
}, 500);
}, function (name,cb) {
setTimeout(function () {
log("1.3 handler: " + name + " B");
cb(null, name);
}, 150);
}
], "aaa", function (err) {
log('1.3 err: ', err);
});
//10.669> 1.3 handler: aaa A
//10.831> 1.3 handler: aaa B
//10.834> 1.3 err: null


56 changes: 34 additions & 22 deletions auto.js
Original file line number Diff line number Diff line change
@@ -1,17 +1,15 @@
var async = require('async');

var t = require('./t');
var log = t.log;

/**
* async.auto用来处理有依赖关系的多个任务的执行。比如某些任务之间彼此独立,可以并行执行;但某些任务依赖于其它某些任务,只能等那些任务完成后才能执行。
*
* 虽然我们可以使用async.parallel和async.series结合起来实现该功能,但如果任务之间关系复杂,则代码会相当复杂,以后如果想添加一个新任务,也会很麻烦。
* auto用来处理有依赖关系的多个任务的执行。
*
* 这时使用async.auto,则会事半功倍。
* 比如某些任务之间彼此独立,可以并行执行;但某些任务依赖于其它某些任务,只能等那些任务完成后才能执行。
* 虽然我们可以使用parallel和series结合起来实现该功能,但如果任务之间关系复杂,则代码会相当复杂,以后如果想添加一个新任务,也会很麻烦。
* 这时使用auto,则会事半功倍。
*
* 如果有任务中途出错,则会把该错误传给最终callback,所有任务(包括已经执行完的)产生的数据将被忽略。
*
* 如果不关心错误和最终数据,可以不用写最后那个callback。
*/
// async.auto(tasks, [callback])
Expand All @@ -24,21 +22,20 @@ var log = t.log;
* 4. 发送邮件,将文件以附件形式发送给其它人。
*
* 分析该任务,可以知道1与2可以并行执行,3需要等1和2完成,4要等3完成。
*
* 可以按以下方式来使用auto函数。
*/
// 1.1
async.auto({
getData: function (callback) {
setTimeout(function(){
console.log('1.1: got data');
callback();
callback(null, 'mydata');
}, 300);
},
makeFolder: function (callback) {
setTimeout(function(){
console.log('1.1: made folder');
callback();
callback(null, 'myfolder');
}, 200);
},
writeFile: ['getData', 'makeFolder', function(callback) {
Expand All @@ -48,20 +45,28 @@ async.auto({
}, 300);
}],
emailFiles: ['writeFile', function(callback, results) {
log('1.1: emailed file: ', results.writeFile); // -> myfile
log('1.1: emailed file: ', results.writeFile);
callback(null, results.writeFile);
}]
}, function(err, results) {
log('1.1: err: ', err); // -> null
log('1.1: results: ', results); // -> { makeFolder: undefined,
// getData: undefined,
// writeFile: 'myfile',
// emailFiles: 'myfile' }
log('1.1: err: ', err);
log('1.1: results: ', results);
});
//1.1: made folder
//1.1: got data
//1.1: wrote file
//20.120> 1.1: emailed file: myfile
//20.125> 1.1: err: null
//20.127> 1.1: results: { makeFolder: 'myfolder',
// getData: 'mydata',
// writeFile: 'myfile',
// emailFiles: 'myfile' }



/**
* 如果中途出错,则会把错误交给最终callback,所有任务(包括执行完的和未执行完的)产生的数据都被忽略。
*/
* 如果中途出错,则会把错误交给最终callback,执行完任务的传给最终callback。未执行完成的函数值被忽略
*/
// 1.2
async.auto({
getData: function (callback) {
Expand All @@ -76,17 +81,24 @@ async.auto({
callback(null, 'myfolder');
}, 200);
},
writeFile: ['getData', 'makeFolder', function(callback, results) {
writeFile: ['getData', 'makeFolder', function(results, callback) {
setTimeout(function(){
console.log('1.2: wrote file');
callback('myerr');
}, 300);
}],
emailFiles: ['writeFile', function(callback, results) {
emailFiles: ['writeFile', function(results, callback) {
console.log('1.2: emailed file: ' + results.writeFile);
callback('err sending email', results.writeFile);
}]
}, function(err, results) {
log('1.2 err: ', err); // -> myerr
log('1.2 results: ', results); // -> ''
});
log('1.2 err: ', err);
log('1.2 results: ', results);
});
//1.2: made folder
//1.2: got data
//1.2: wrote file
//51.399> 1.2 err: myerr
//51.401> 1.2 results: { makeFolder: 'myfolder',
// getData: 'mydata',
// writeFile: undefined }
86 changes: 86 additions & 0 deletions cargo.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
var async = require('async');
var t = require('./t');
var log = t.log;

/**
* cargo也是一个串行的消息队列,类似于queue,通过限制了worker数量,不再一次性全部执行。
* 当worker数量不够用时,新加入的任务将会排队等候,直到有新的worker可用。
*
* cargo的不同之处在于,cargo每次会加载满额的任务做为任务单元,只有任务单元中全部执行完成后,才会加载新的任务单元。
*/
// cargo(worker, [payload])

/**
* 创建cargo实例
*/
var cargo = async.cargo(function (tasks, callback) {
for(var i=0; i<tasks.length; i++){
log('start ' + tasks[i].name);
}
callback();
}, 2);


/**
* 监听:如果某次push操作后,任务数将达到或超过worker数量时,将调用该函数
*/
cargo.saturated = function() {
log('all workers to be used');
}

/**
* 监听:当最后一个任务交给worker时,将调用该函数
*/
cargo.empty = function() {
log('no more tasks wating');
}

/**
* 监听:当所有任务都执行完以后,将调用该函数
*/
cargo.drain = function() {
log('all tasks have been processed');
}

/**
* 增加新任务
*/
cargo.push({name: 'A'}, function (err) {
t.wait(300);
log('finished processing A');
});
cargo.push({name: 'B'}, function (err) {
t.wait(600);
log('finished processing B');
});
cargo.push({name: 'C'}, function (err) {
t.wait(500);
log('finished processing C');
});
cargo.push({name: 'D'}, function (err) {
t.wait(100);
log('finished processing D');
});
cargo.push({name: 'E'}, function (err) {
t.wait(200);
log('finished processing E');
});
//40.016> all workers to be used
//40.020> no more tasks wating
//40.020> start A
//40.020> start B
//40.322> finished processing A
//40.923> finished processing B
//40.923> no more tasks wating
//40.924> start C
//40.924> start D
//41.425> finished processing C
//41.526> finished processing D
//41.526> no more tasks wating
//41.527> start E
//41.728> finished processing E
//41.728> all tasks have been processed
//41.729> all tasks have been processed
//41.729> all tasks have been processed
//41.729> all tasks have been processed
//41.730> all tasks have been processed
Loading