From 6978469461dd61c2ce0a0f41b277e9338681e251 Mon Sep 17 00:00:00 2001 From: alsotang Date: Wed, 19 Sep 2012 02:35:47 +0800 Subject: [PATCH 01/36] add *package.json* so people can get the dependencies conveniently. --- .gitignore | 1 + README.md | 4 +++- package.json | 9 +++++++++ 3 files changed, 13 insertions(+), 1 deletion(-) create mode 100644 .gitignore create mode 100644 package.json diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..c2658d7 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +node_modules/ diff --git a/README.md b/README.md index e7b4fdf..08f8062 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,6 @@ async_demo ========== -A demo for async \ No newline at end of file +A demo for async. + +run `npm install` before you run the codes here. diff --git a/package.json b/package.json new file mode 100644 index 0000000..f2f0b42 --- /dev/null +++ b/package.json @@ -0,0 +1,9 @@ +{ + "name": "async_demo", + "version": "0.1.1", + "private": true, + "dependencies": { + "moment": "*", + "async": "*" + } +} From fc49798f59ce43bd42088bfff4abfd0358f2655f Mon Sep 17 00:00:00 2001 From: alsotang Date: Wed, 19 Sep 2012 03:33:02 +0800 Subject: [PATCH 02/36] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E4=BA=86=E6=9B=B4?= =?UTF-8?q?=E5=A4=9A=E6=B3=A8=E9=87=8A=20=E5=A4=A7=E5=8A=9B=E4=BF=AE?= =?UTF-8?q?=E6=AD=A3=E4=BA=86=E5=8E=9F=E6=9D=A5=E4=B8=8D=E6=B8=85=E4=B8=8D?= =?UTF-8?q?=E6=A5=9A=E7=9A=84'iterator.js'=20=E4=BF=AE=E6=AD=A3=E4=BA=86'w?= =?UTF-8?q?aterfall'=E9=87=8C=E9=9D=A2=E7=9A=84=E4=B8=80=E4=B8=AA=E5=B0=8F?= =?UTF-8?q?=E9=94=99=E8=AF=AF=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- detect.js | 2 +- iterator.js | 41 ++++++++++++++++++++++++----------------- series.js | 2 +- t.js | 10 +++++++++- waterfall.js | 6 +++--- 5 files changed, 38 insertions(+), 23 deletions(-) diff --git a/detect.js b/detect.js index ba74518..fe2b563 100644 --- a/detect.js +++ b/detect.js @@ -39,4 +39,4 @@ async.detectSeries(arr, function(item,callback) { log('1.2 result: ', result); }); // 09.928> 1.2 enter: 1 -// 10.438> 1.2 result: { value: 1, delay: 500 } \ No newline at end of file +// 10.438> 1.2 result: { value: 1, delay: 500 } diff --git a/iterator.js b/iterator.js index a55fc55..a2c2be2 100644 --- a/iterator.js +++ b/iterator.js @@ -4,33 +4,40 @@ var t = require('./t'); var log = t.log; /** - * 将一组函数包装成为一个iterator,可通过next()得到以下一个函数为起点的新的iterator。该函数通常由async在内部使用,但如果需要时,也可在我们的代码中使用它。 + * 将一组函数包装成为一个iterator,初次调用此iterator时,会执行定义中的第一个函数并返回第二个函数以供调用。 + * 也可通过手动调用 next() 得到以下一个函数为起点的新的iterator。 + * 该函数通常由async在内部使用,但如果需要时,也可在我们的代码中使用它。 */ // async.iterator(tasks) var iter = async.iterator([ - function() { console.log('111') }, - function() { console.log('222') }, - function() { console.log('333') } + function() { console.log('I am 111') }, + function() { console.log('I am 222') }, + function() { console.log('I am 333') } ]); // 直接调用(),会执行当前函数,并返回一个由下个函数为起点的新的iterator console.log('------- iter() ---------'); -console.log(iter()); -console.log(iter()); +var it1 = iter(); // => 'I am 111' +it1(); // => 'I am 222' +it1(); // => 'I am 222' +it1(); // => 'I am 222' + +console.log('----'); + +var it2 = iter(); // => 'I am 111' +var it3 = it2(); // => 'I am 222' +var it4 = it3(); // => 'I am 333' +// it4(); // 这句代码执行会报错 +console.log(it4); // => 'null' // 调用next(),不会执行当前函数,直接返回由下个函数为起点的新iterator +// 对于同一个iterator,多次调用next(),不会影响自己 console.log('-------- iter.next() -------'); -console.log(iter.next()); -console.log(iter.next()); -console.log(iter.next()); -console.log(iter.next()); +var it5 = iter.next(); +it5(); // => 'I am 222' +var it6 = iter.next().next(); +it6(); // => 'I am 333' +iter(); // => 'I am 111' -// 对于同一个iterator,多次调用next(),不会影响自己 -console.log('-------- iter.next()() -------'); -console.log(iter.next()()); -console.log(iter.next()()); -// 如果只有一个元素,则next()返回null -console.log('--------- last.next() --------'); -console.log(iter.next().next().next()); \ No newline at end of file diff --git a/series.js b/series.js index 430021f..ee1b1b3 100644 --- a/series.js +++ b/series.js @@ -68,4 +68,4 @@ async.series({ }, function (err, results) { log('1.4 err: ', err); // -> myerr log('1.4 results: ', results); // -> { a: 4, b: undefined, c: undefined } -}); \ No newline at end of file +}); diff --git a/t.js b/t.js index 71b9e33..65bb4c7 100644 --- a/t.js +++ b/t.js @@ -1,6 +1,10 @@ +// 其实这个文件名的't'我不是很明白原作者freewind的意思,我觉得叫做'lib.js'或者 +// 'helper.js'比较合适,因为这里面都是些辅助函数。 + var moment = require('moment'); exports.inc = function(n, callback, timeout) { + //将参数n自增1之后的结果返回给async timeout = timeout || 200; setTimeout(function() { callback(null, n+1); @@ -8,6 +12,7 @@ exports.inc = function(n, callback, timeout) { }; exports.fire = function(obj, callback, timeout) { + //直接将obj的内容返回给async timeout = timeout || 200; setTimeout(function() { callback(null, obj); @@ -15,6 +20,7 @@ exports.fire = function(obj, callback, timeout) { }; exports.err = function(errMsg, callback, timeout) { + //模拟一个错误的产生,让async各个函数末尾的callback接收到。 timeout = timeout || 200; setTimeout(function() { callback(errMsg); @@ -23,6 +29,7 @@ exports.err = function(errMsg, callback, timeout) { // utils exports.log = function(msg, obj) { + //对console.log进行了封装。主要是增加了秒钟的输出,通过秒数的差值方便大家对async的理解。 process.stdout.write(moment().format('ss.SSS')+'> '); if(obj!==undefined) { process.stdout.write(msg); @@ -33,6 +40,7 @@ exports.log = function(msg, obj) { }; exports.wait = function(mils) { + //刻意等待mils的时间,mils的单位是毫秒。 var now = new Date; while(new Date - now <= mils); -} \ No newline at end of file +} diff --git a/waterfall.js b/waterfall.js index ddf938b..0acf550 100644 --- a/waterfall.js +++ b/waterfall.js @@ -1,7 +1,7 @@ var async = require('async'); /** - * 按顺序依次执行一组函数。每个函数产生的值,都将传给下一个。如果中途出错,后面的函数将不会被执行。错误信息以及之前产生的结果,将传给waterfall最终的callback。 + * 按顺序依次执行一组函数。每个函数产生的值,都将传给下一个。如果中途出错,后面的函数将不会被执行。错误信息将传给waterfall最终的callback。之前产生的结果被丢弃。 * * 这个函数名为waterfall(瀑布),可以想像瀑布从上到下,中途冲过一层层突起的石头。 * @@ -28,7 +28,7 @@ async.waterfall([ }); /** - * 中途有函数出错,其err和产生的值将直接传给最终callback,后面的函数不再执行。 + * 中途有函数出错,其err直接传给最终callback,结果被丢弃,后面的函数不再执行。 */ // 1.2 async.waterfall([ @@ -52,4 +52,4 @@ async.waterfall({ }, function (err, result) { log('1.3 err: ', err); // -> undefined log('1.3 result: ', result); // -> undefined -}); \ No newline at end of file +}); From bfcb64a3f83665fb178ad6790662b3bbc069afb0 Mon Sep 17 00:00:00 2001 From: palmtoy Date: Sun, 1 Sep 2013 07:27:34 +0800 Subject: [PATCH 03/36] del undefined x at line 14 --- nextTick.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/nextTick.js b/nextTick.js index 2c7b6fd..3532e37 100644 --- a/nextTick.js +++ b/nextTick.js @@ -11,10 +11,10 @@ var calls = []; async.nextTick(function() { calls.push('two'); -});x +}); calls.push('one'); async.nextTick(function() { console.log(calls); // -> [ 'one', 'two' ] -}); \ No newline at end of file +}); From d2d3455a58f1f158c9a633e64d188d055d2a2133 Mon Sep 17 00:00:00 2001 From: bsspirit Date: Thu, 12 Sep 2013 10:33:18 +0800 Subject: [PATCH 04/36] 'update1' --- .idea/scopes/scope_settings.xml | 5 + .idea/workspace.xml | 297 ++++++++++++++++++++++++++++++++ README.md | 18 +- each.js | 145 ++++++++++++++++ filter.js | 112 ++++++++++++ 5 files changed, 576 insertions(+), 1 deletion(-) create mode 100644 .idea/scopes/scope_settings.xml create mode 100644 .idea/workspace.xml create mode 100644 each.js create mode 100644 filter.js diff --git a/.idea/scopes/scope_settings.xml b/.idea/scopes/scope_settings.xml new file mode 100644 index 0000000..922003b --- /dev/null +++ b/.idea/scopes/scope_settings.xml @@ -0,0 +1,5 @@ + + + + \ No newline at end of file diff --git a/.idea/workspace.xml b/.idea/workspace.xml new file mode 100644 index 0000000..69f4d8e --- /dev/null +++ b/.idea/workspace.xml @@ -0,0 +1,297 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1378913906289 + 1378913906289 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/README.md b/README.md index 08f8062..b0451ba 100644 --- a/README.md +++ b/README.md @@ -3,4 +3,20 @@ async_demo A demo for async. -run `npm install` before you run the codes here. +INSTALL +=========================== + +> git clone https://github.com/caolan/async.git nodejs-async + +> cd nodejs-async && npm install + +Change Log by bsspirit +=================================== + + 参考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改名为filter.js \ No newline at end of file diff --git a/each.js b/each.js new file mode 100644 index 0000000..9de19df --- /dev/null +++ b/each.js @@ -0,0 +1,145 @@ +var async = require('async'); + +var t = require('./t'); +var log = t.log; + +/** + * 如果想对同一个集合中的所有元素都执行同一个异步操作,可以利用each函数。 + * + * async提供了三种方式: + * 1. 集合中所有元素并行执行 + * 2. 一个一个顺序执行 + * 3. 分批执行,同一批内并行,批与批之间按顺序 + * + * 如果中途出错,则错误将上传给最终的callback处理。其它已经启动的任务继续执行,未启动的忽略。 + */ +// each(arr, iterator(item, callback), callback(err)) + + +var arr = [{name:'Jack', delay: 200}, + {name:'Mike', delay: 100}, + {name:'Freewind', delay: 300}]; + +/** + * 所有操作并发执行,且全部未出错,最终得到的err为undefined。注意最终callback只有一个参数err。 + */ +// 1.1 +async.each(arr, function(item, callback) { + log('1.1 enter: ' + item.name); + setTimeout(function(){ + log('1.1 handle: ' + item.name); + callback(null, item.name); + }, item.delay); +}, function(err) { + log('1.1 err: ' + err); +}); +// 输出如下: +// 42.244> 1.1 enter: Jack +// 42.245> 1.1 enter: Mike +// 42.245> 1.1 enter: Freewind +// 42.350> 1.1 handle: Mike +// 42.445> 1.1 handle: Jack +// 42.554> 1.1 handle: Freewind +// 42.554> 1.1 err: undefined + + +/** + * 如果中途出错,则出错后马上调用最终的callback。其它未执行完的任务继续执行。 + */ +async.each(arr,function(item, callback) { + log('1.2 enter: ' +item.name); + setTimeout(function() { + log('1.2 handle: ' + item.name); + if(item.name==='Jack') { + callback('myerr'); + } + }, item.delay); +}, function(err) { + log('1.2 err: ' + err); +}); +// 输出如下: +// 42.246> 1.2 enter: Jack +// 42.246> 1.2 enter: Mike +// 42.246> 1.2 enter: Freewind +// 42.350> 1.2 handle: Mike +// 42.445> 1.2 handle: Jack +// 42.446> 1.2 err: myerr +// 42.555> 1.2 handle: Freewind + +/** + * 与each相似,但不是并行执行。而是一个个按顺序执行。 + */ +async.eachSeries(arr, function(item, callback) { + log('1.3 enter: ' + item.name); + setTimeout(function(){ + log('1.3 handle: ' + item.name); + callback(null, item.name); + }, item.delay); +}, function(err) { + log('1.3 err: ' + err); +}); +// 42.247> 1.3 enter: Jack +// 42.459> 1.3 handle: Jack +// 42.459> 1.3 enter: Mike +// 42.569> 1.3 handle: Mike +// 42.569> 1.3 enter: Freewind +// 42.883> 1.3 handle: Freewind +// 42.883> 1.3 err: undefined + +/** + * 如果中途出错,则马上把错误传给最终的callback,还未执行的不再执行。 + */ +async.eachSeries(arr,function(item, callback) { + log('1.4 enter: ' +item.name); + setTimeout(function() { + log('1.4 handle: ' + item.name); + if(item.name==='Jack') { + callback('myerr'); + } + }, item.delay); +}, function(err) { + log('1.4 err: ' + err); +}); +// 42.247> 1.4 enter: Jack +// 42.460> 1.4 handle: Jack +// 42.460> 1.4 err: myerr + +/** + * 分批执行,第二个参数是每一批的个数。每一批内并行执行,但批与批之间按顺序执行。 + */ +async.eachLimit(arr, 2, function(item, callback) { + log('1.5 enter: ' + item.name); + setTimeout(function(){ + log('1.5 handle: ' + item.name); + callback(null, item.name); + }, item.delay); +}, function(err) { + log('1.5 err: ' + err); +}); +// 42.247> 1.5 enter: Jack +// 42.248> 1.5 enter: Mike +// 42.351> 1.5 handle: Mike +// 42.352> 1.5 enter: Freewind +// 42.461> 1.5 handle: Jack +// 42.664> 1.5 handle: Freewind +// 42.664> 1.5 err: undefined + +/** + * 如果中途出错,错误将马上传给最终的callback。同一批中的未执行完的任务还将继续执行,但下一批及以后的不再执行。 + */ +async.eachLimit(arr,2,function(item, callback) { + log('1.6 enter: ' +item.name); + setTimeout(function() { + log('1.6 handle: ' + item.name); + if(item.name==='Jack') { + callback('myerr'); + } + }, item.delay); +}, function(err) { + log('1.6 err: ' + err); +}); +// 42.248> 1.6 enter: Jack +// 42.248> 1.6 enter: Mike +// 42.352> 1.6 handle: Mike +// 42.462> 1.6 handle: Jack +// 42.462> 1.6 err: myerr \ No newline at end of file diff --git a/filter.js b/filter.js new file mode 100644 index 0000000..4ab2f04 --- /dev/null +++ b/filter.js @@ -0,0 +1,112 @@ +var async = require('async'); + +var t = require('./t'); +var log = t.log; + +/** + * 使用异步操作对集合中的元素进行筛选。需要注意的是,iterator的callback只有一个参数,只能接收true或false。 + * + * 对于出错,该函数没有做出任何处理,直接由nodejs抛出。所以需要注意对Error的处理。 + * + * async提供了两种方式: + * 1. 并行执行:filter + * 2. 顺序执行:filterSereis + */ +// filter(arr, iterator(item, callback(test)), callback(results)) + +var arr = [1,2,3,4,5]; + +/** + * 并行执行,对arr进行筛选。 + */ +async.filter(arr, function(item, callback) { + log('1.1 enter: ' + item); + setTimeout(function() { + log('1.1 test: ' + item); + callback(item>=3); + }, 200); +}, function(results) { + log('1.1 results: ', results); +}); +// 16.739> 1.1 enter: 1 +// 16.749> 1.1 enter: 2 +// 16.749> 1.1 enter: 3 +// 16.749> 1.1 enter: 4 +// 16.749> 1.1 enter: 5 +// 16.749> 1.3 enter: 1 +// 16.949> 1.1 test: 1 +// 16.949> 1.1 test: 2 +// 16.949> 1.1 test: 3 +// 16.949> 1.1 test: 4 +// 16.949> 1.1 test: 5 +// 16.949> 1.1 results: [ 3, 4, 5 ] + + +/** + * 如果出错,将会由nodejs抛出,导致出错。为保证其它代码正常运行,注释掉该测试。 + */ +/* +async.filter(arr, function(item, callback) { + log('1.2 enter: ' + item); + setTimeout(function() { + log('1.2 handle: ' + item); + if(item===2) { + throw new Error('myerr'); + } + callback(item>=3); + }, 100); +}, function(results) { + log('1.2 results: ', results); +}); +*/ + +/** + * 并行执行,对arr进行筛选。 + */ +// 1.3 +async.filterSeries(arr, function(item, callback) { + log('1.3 enter: ' + item); + setTimeout(function() { + log('1.3 handle: ' + item); + callback(item>=3); + }, 200); +}, function(results) { + log('1.3 results: ', results); +}); +// 16.749> 1.3 enter: 1 +// 16.949> 1.3 handle: 1 +// 16.949> 1.3 enter: 2 +// 17.149> 1.3 handle: 2 +// 17.149> 1.3 enter: 3 +// 17.369> 1.3 handle: 3 +// 17.369> 1.3 enter: 4 +// 17.589> 1.3 handle: 4 +// 17.589> 1.3 enter: 5 +// 17.789> 1.3 handle: 5 +// 17.789> 1.3 results: [ 3, 4, 5 ] + + +/* + * reject跟filter正好相反,当测试为true时,抛弃之 + */ +// reject(arr, iterator(item, callback(test)), callback(results) +async.reject(arr, function(item, callback) { + log('1.4 enter: ' + item); + setTimeout(function() { + log('1.4 test: ' + item); + callback(item>=3); + }, 200); +}, function(results) { + log('1.4 results: ', results); +}); +// 31.359> 1.4 enter: 1 +// 31.359> 1.4 enter: 2 +// 31.359> 1.4 enter: 3 +// 31.359> 1.4 enter: 4 +// 31.359> 1.4 enter: 5 +// 31.559> 1.4 test: 1 +// 31.559> 1.4 test: 2 +// 31.559> 1.4 test: 3 +// 31.559> 1.4 test: 4 +// 31.559> 1.4 test: 5 +// 31.569> 1.4 results: [ 1, 2 ] \ No newline at end of file From d9c26e61172ed70fe872a640a530f2769e047e4b Mon Sep 17 00:00:00 2001 From: bsspirit Date: Thu, 12 Sep 2013 10:34:51 +0800 Subject: [PATCH 05/36] update1 --- .gitignore | 1 + .idea/workspace.xml | 31 +++++++--- README.md | 5 +- filter_reject.js | 112 ---------------------------------- forEach.js | 145 -------------------------------------------- 5 files changed, 25 insertions(+), 269 deletions(-) delete mode 100644 filter_reject.js delete mode 100644 forEach.js diff --git a/.gitignore b/.gitignore index c2658d7..a5199f6 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ node_modules/ +.idea \ No newline at end of file diff --git a/.idea/workspace.xml b/.idea/workspace.xml index 69f4d8e..e087389 100644 --- a/.idea/workspace.xml +++ b/.idea/workspace.xml @@ -8,6 +8,7 @@ + - + - + + + + + + + + + + @@ -73,6 +83,7 @@ @@ -248,13 +259,6 @@ - - - - - - - @@ -287,7 +291,14 @@ - + + + + + + + + diff --git a/README.md b/README.md index b0451ba..2141472 100644 --- a/README.md +++ b/README.md @@ -13,8 +13,9 @@ INSTALL Change Log by bsspirit =================================== - 参考async@0.2.9版本的规范 - https://github.com/caolan/async +参考async@0.2.9版本的规范 + +https://github.com/caolan/async 1. forEach.js改名为each.js 2. each.js文件中的async.forEach,改为async.each diff --git a/filter_reject.js b/filter_reject.js deleted file mode 100644 index 2e4b0af..0000000 --- a/filter_reject.js +++ /dev/null @@ -1,112 +0,0 @@ -var async = require('async'); - -var t = require('./t'); -var log = t.log; - -/** - * 使用异步操作对集合中的元素进行筛选。需要注意的是,iterator的callback只有一个参数,只能接收true或false。 - * - * 对于出错,该函数没有做出任何处理,直接由nodejs抛出。所以需要注意对Error的处理。 - * - * async提供了两种方式: - * 1. 并行执行:filter - * 2. 顺序执行:filterSereis - */ -// filter(arr, iterator(item, callback(test)), callback(results)) - -var arr = [1,2,3,4,5]; - -/** - * 并行执行,对arr进行筛选。 - */ -async.filter(arr, function(item, callback) { - log('1.1 enter: ' + item); - setTimeout(function() { - log('1.1 test: ' + item); - callback(item>=3); - }, 200); -}, function(results) { - log('1.1 results: ', results); -}); -// 16.739> 1.1 enter: 1 -// 16.749> 1.1 enter: 2 -// 16.749> 1.1 enter: 3 -// 16.749> 1.1 enter: 4 -// 16.749> 1.1 enter: 5 -// 16.749> 1.3 enter: 1 -// 16.949> 1.1 test: 1 -// 16.949> 1.1 test: 2 -// 16.949> 1.1 test: 3 -// 16.949> 1.1 test: 4 -// 16.949> 1.1 test: 5 -// 16.949> 1.1 results: [ 3, 4, 5 ] - - -/** - * 如果出错,将会由nodejs抛出,导致出错。为保证其它代码正常运行,注释掉该测试。 - */ -/* -async.filter(arr, function(item, callback) { - log('1.2 enter: ' + item); - setTimeout(function() { - log('1.2 handle: ' + item); - if(item===2) { - throw new Error('myerr'); - } - callback(item>=3); - }, 100); -}, function(results) { - log('1.2 results: ', results); -}); -*/ - -/** - * 并行执行,对arr进行筛选。 - */ -// 1.3 -async.filterSeries(arr, function(item, callback) { - log('1.3 enter: ' + item); - setTimeout(function() { - log('1.3 handle: ' + item); - callback(item>=3); - }, 200); -}, function(results) { - log('1.3 results: ', results); -}); -// 16.749> 1.3 enter: 1 -// 16.949> 1.3 handle: 1 -// 16.949> 1.3 enter: 2 -// 17.149> 1.3 handle: 2 -// 17.149> 1.3 enter: 3 -// 17.369> 1.3 handle: 3 -// 17.369> 1.3 enter: 4 -// 17.589> 1.3 handle: 4 -// 17.589> 1.3 enter: 5 -// 17.789> 1.3 handle: 5 -// 17.789> 1.3 results: [ 3, 4, 5 ] - - -/* - * reject跟filter正好相反,当测试为true时,抛弃之 - */ -// reject(arr, iterator(item, callback(test)), callback(results) -async.reject(arr, function(item, callback) { - log('1.4 enter: ' + item); - setTimeout(function() { - log('1.4 test: ' + item); - callback(item>=3); - }, 200); -}, function(results) { - log('1.4 results: ', results); -}); -// 31.359> 1.4 enter: 1 -// 31.359> 1.4 enter: 2 -// 31.359> 1.4 enter: 3 -// 31.359> 1.4 enter: 4 -// 31.359> 1.4 enter: 5 -// 31.559> 1.4 test: 1 -// 31.559> 1.4 test: 2 -// 31.559> 1.4 test: 3 -// 31.559> 1.4 test: 4 -// 31.559> 1.4 test: 5 -// 31.569> 1.4 results: [ 1, 2 ] \ No newline at end of file diff --git a/forEach.js b/forEach.js deleted file mode 100644 index 324f338..0000000 --- a/forEach.js +++ /dev/null @@ -1,145 +0,0 @@ -var async = require('async'); - -var t = require('./t'); -var log = t.log; - -/** - * 如果想对同一个集合中的所有元素都执行同一个异步操作,可以利用forEach函数。 - * - * async提供了三种方式: - * 1. 集合中所有元素并行执行 - * 2. 一个一个顺序执行 - * 3. 分批执行,同一批内并行,批与批之间按顺序 - * - * 如果中途出错,则错误将上传给最终的callback处理。其它已经启动的任务继续执行,未启动的忽略。 - */ -// forEach(arr, iterator(item, callback), callback(err)) - - -var arr = [{name:'Jack', delay: 200}, - {name:'Mike', delay: 100}, - {name:'Freewind', delay: 300}]; - -/** - * 所有操作并发执行,且全部未出错,最终得到的err为undefined。注意最终callback只有一个参数err。 - */ -// 1.1 -async.forEach(arr, function(item, callback) { - log('1.1 enter: ' + item.name); - setTimeout(function(){ - log('1.1 handle: ' + item.name); - callback(null, item.name); - }, item.delay); -}, function(err) { - log('1.1 err: ' + err); -}); -// 输出如下: -// 42.244> 1.1 enter: Jack -// 42.245> 1.1 enter: Mike -// 42.245> 1.1 enter: Freewind -// 42.350> 1.1 handle: Mike -// 42.445> 1.1 handle: Jack -// 42.554> 1.1 handle: Freewind -// 42.554> 1.1 err: undefined - - -/** - * 如果中途出错,则出错后马上调用最终的callback。其它未执行完的任务继续执行。 - */ -async.forEach(arr,function(item, callback) { - log('1.2 enter: ' +item.name); - setTimeout(function() { - log('1.2 handle: ' + item.name); - if(item.name==='Jack') { - callback('myerr'); - } - }, item.delay); -}, function(err) { - log('1.2 err: ' + err); -}); -// 输出如下: -// 42.246> 1.2 enter: Jack -// 42.246> 1.2 enter: Mike -// 42.246> 1.2 enter: Freewind -// 42.350> 1.2 handle: Mike -// 42.445> 1.2 handle: Jack -// 42.446> 1.2 err: myerr -// 42.555> 1.2 handle: Freewind - -/** - * 与forEach相似,但不是并行执行。而是一个个按顺序执行。 - */ -async.forEachSeries(arr, function(item, callback) { - log('1.3 enter: ' + item.name); - setTimeout(function(){ - log('1.3 handle: ' + item.name); - callback(null, item.name); - }, item.delay); -}, function(err) { - log('1.3 err: ' + err); -}); -// 42.247> 1.3 enter: Jack -// 42.459> 1.3 handle: Jack -// 42.459> 1.3 enter: Mike -// 42.569> 1.3 handle: Mike -// 42.569> 1.3 enter: Freewind -// 42.883> 1.3 handle: Freewind -// 42.883> 1.3 err: undefined - -/** - * 如果中途出错,则马上把错误传给最终的callback,还未执行的不再执行。 - */ -async.forEachSeries(arr,function(item, callback) { - log('1.4 enter: ' +item.name); - setTimeout(function() { - log('1.4 handle: ' + item.name); - if(item.name==='Jack') { - callback('myerr'); - } - }, item.delay); -}, function(err) { - log('1.4 err: ' + err); -}); -// 42.247> 1.4 enter: Jack -// 42.460> 1.4 handle: Jack -// 42.460> 1.4 err: myerr - -/** - * 分批执行,第二个参数是每一批的个数。每一批内并行执行,但批与批之间按顺序执行。 - */ -async.forEachLimit(arr, 2, function(item, callback) { - log('1.5 enter: ' + item.name); - setTimeout(function(){ - log('1.5 handle: ' + item.name); - callback(null, item.name); - }, item.delay); -}, function(err) { - log('1.5 err: ' + err); -}); -// 42.247> 1.5 enter: Jack -// 42.248> 1.5 enter: Mike -// 42.351> 1.5 handle: Mike -// 42.352> 1.5 enter: Freewind -// 42.461> 1.5 handle: Jack -// 42.664> 1.5 handle: Freewind -// 42.664> 1.5 err: undefined - -/** - * 如果中途出错,错误将马上传给最终的callback。同一批中的未执行完的任务还将继续执行,但下一批及以后的不再执行。 - */ -async.forEachLimit(arr,2,function(item, callback) { - log('1.6 enter: ' +item.name); - setTimeout(function() { - log('1.6 handle: ' + item.name); - if(item.name==='Jack') { - callback('myerr'); - } - }, item.delay); -}, function(err) { - log('1.6 err: ' + err); -}); -// 42.248> 1.6 enter: Jack -// 42.248> 1.6 enter: Mike -// 42.352> 1.6 handle: Mike -// 42.462> 1.6 handle: Jack -// 42.462> 1.6 err: myerr \ No newline at end of file From 61b7cf588008b24e03415fa37c7ac88be62a86da Mon Sep 17 00:00:00 2001 From: bsspirit Date: Thu, 12 Sep 2013 10:36:59 +0800 Subject: [PATCH 06/36] remove_idea --- .gitignore | 3 +- .idea/scopes/scope_settings.xml | 5 - .idea/workspace.xml | 308 -------------------------------- 3 files changed, 1 insertion(+), 315 deletions(-) delete mode 100644 .idea/scopes/scope_settings.xml delete mode 100644 .idea/workspace.xml diff --git a/.gitignore b/.gitignore index a5199f6..40b878d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1 @@ -node_modules/ -.idea \ No newline at end of file +node_modules/ \ No newline at end of file diff --git a/.idea/scopes/scope_settings.xml b/.idea/scopes/scope_settings.xml deleted file mode 100644 index 922003b..0000000 --- a/.idea/scopes/scope_settings.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - \ No newline at end of file diff --git a/.idea/workspace.xml b/.idea/workspace.xml deleted file mode 100644 index e087389..0000000 --- a/.idea/workspace.xml +++ /dev/null @@ -1,308 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1378913906289 - 1378913906289 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - From 1d67241b8797673e747f9445fe5ba811c5be415b Mon Sep 17 00:00:00 2001 From: bsspirit Date: Thu, 12 Sep 2013 10:37:56 +0800 Subject: [PATCH 07/36] 'ignore' --- .gitignore | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 40b878d..a5199f6 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ -node_modules/ \ No newline at end of file +node_modules/ +.idea \ No newline at end of file From 292c3a1d033254c6ff94bad3e80bafa2b363c59d Mon Sep 17 00:00:00 2001 From: bsspirit Date: Thu, 12 Sep 2013 10:57:39 +0800 Subject: [PATCH 08/36] reject --- README.md | 5 +-- filter.js => filter_reject.js | 66 +++++++++++++++++++++++++---------- 2 files changed, 50 insertions(+), 21 deletions(-) rename filter.js => filter_reject.js (66%) diff --git a/README.md b/README.md index 2141472..eed0bbb 100644 --- a/README.md +++ b/README.md @@ -19,5 +19,6 @@ 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改名为filter.js \ No newline at end of file +3. map.js增加mapLimit函数 +4. filter_reject.js对注释进行补充 +5. filter_reject.js增加rejectSeries函数 \ No newline at end of file diff --git a/filter.js b/filter_reject.js similarity index 66% rename from filter.js rename to filter_reject.js index 4ab2f04..cc40ab1 100644 --- a/filter.js +++ b/filter_reject.js @@ -28,23 +28,25 @@ async.filter(arr, function(item, callback) { }, function(results) { log('1.1 results: ', results); }); -// 16.739> 1.1 enter: 1 -// 16.749> 1.1 enter: 2 -// 16.749> 1.1 enter: 3 -// 16.749> 1.1 enter: 4 -// 16.749> 1.1 enter: 5 -// 16.749> 1.3 enter: 1 -// 16.949> 1.1 test: 1 -// 16.949> 1.1 test: 2 -// 16.949> 1.1 test: 3 -// 16.949> 1.1 test: 4 -// 16.949> 1.1 test: 5 -// 16.949> 1.1 results: [ 3, 4, 5 ] +//16.739> 1.1 enter: 1 +//16.749> 1.1 enter: 2 +//16.749> 1.1 enter: 3 +//16.749> 1.1 enter: 4 +//16.749> 1.1 enter: 5 +//16.749> 1.3 enter: 1 +//16.949> 1.1 test: 1 +//16.949> 1.1 test: 2 +//16.949> 1.1 test: 3 +//16.949> 1.1 test: 4 +//16.949> 1.1 test: 5 +//16.949> 1.1 results: [ 3, 4, 5 ] /** - * 如果出错,将会由nodejs抛出,导致出错。为保证其它代码正常运行,注释掉该测试。 - */ +* 如果出错,将会由nodejs抛出,导致出错。为保证其它代码正常运行,注释掉该测试。 +* +* try..catch:抓不到这个错误 +*/ /* async.filter(arr, function(item, callback) { log('1.2 enter: ' + item); @@ -61,8 +63,8 @@ async.filter(arr, function(item, callback) { */ /** - * 并行执行,对arr进行筛选。 - */ +* 串行执行,对arr进行筛选。 +*/ // 1.3 async.filterSeries(arr, function(item, callback) { log('1.3 enter: ' + item); @@ -87,8 +89,8 @@ async.filterSeries(arr, function(item, callback) { /* - * reject跟filter正好相反,当测试为true时,抛弃之 - */ +* reject跟filter正好相反,当测试为true时,抛弃之 +*/ // reject(arr, iterator(item, callback(test)), callback(results) async.reject(arr, function(item, callback) { log('1.4 enter: ' + item); @@ -109,4 +111,30 @@ async.reject(arr, function(item, callback) { // 31.559> 1.4 test: 3 // 31.559> 1.4 test: 4 // 31.559> 1.4 test: 5 -// 31.569> 1.4 results: [ 1, 2 ] \ No newline at end of file +// 31.569> 1.4 results: [ 1, 2 ] + + +/** + * 串行执行,对arr进行筛选。 + */ +// 1.3 +async.rejectSeries(arr, function(item, callback) { + log('1.5 enter: ' + item); + setTimeout(function() { + log('1.5 handle: ' + item); + callback(item>=3); + }, 200); +}, function(results) { + log('1.5 results: ', results); +}); +//43.592> 1.5 enter: 1 +//43.799> 1.5 handle: 1 +//43.800> 1.5 enter: 2 +//44.004> 1.5 handle: 2 +//44.007> 1.5 enter: 3 +//44.210> 1.5 handle: 3 +//44.211> 1.5 enter: 4 +//44.412> 1.5 handle: 4 +//44.413> 1.5 enter: 5 +//44.614> 1.5 handle: 5 +//44.616> 1.5 results: [ 1, 2 ] \ No newline at end of file From 85251c89df4e4485c64173764114a7019ce1a8ba Mon Sep 17 00:00:00 2001 From: bsspirit Date: Thu, 12 Sep 2013 11:13:30 +0800 Subject: [PATCH 09/36] 'reduce' --- README.md | 3 ++- reduce.js | 21 ++++++++++++++++++--- 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index eed0bbb..6c8124e 100644 --- a/README.md +++ b/README.md @@ -21,4 +21,5 @@ https://github.com/caolan/async 2. each.js文件中的async.forEach,改为async.each 3. map.js增加mapLimit函数 4. filter_reject.js对注释进行补充 -5. filter_reject.js增加rejectSeries函数 \ No newline at end of file +5. filter_reject.js增加rejectSeries函数 +5. reduce.js增加注释 \ No newline at end of file diff --git a/reduce.js b/reduce.js index 6b5e72a..879b300 100644 --- a/reduce.js +++ b/reduce.js @@ -4,13 +4,16 @@ var t = require('./t'); var log = t.log; /** - * ReduceǸһʼֵ뼯еÿһԪ㣬õһֵreduceԪأ󣬿ʹreduceRight + * Reduce可以让我们给定一个初始值,用它与集合中的每一个元素做运算,最后得到一个值。reduce从左向右来遍历元素,如果想从右向左,可使用reduceRight。 */ //reduce(arr, memo, iterator(memo,item,callback), callback(err,result)) //alias: inject, foldl var arr = [1,3,5]; +/** + * 顺序执行 + */ async.reduce(arr, 100, function(memo, item, callback) { log('1.1 enter: ' + memo +', ' + item); setTimeout(function() { @@ -26,6 +29,9 @@ async.reduce(arr, 100, function(memo, item, callback) { // 29.109> 1.1 err: // 29.109> 1.1 result: 109 +/** + * 顺序执行过程中出错,只把错误传给最终callback,结果是null + */ async.reduce(arr, 100, function(memo, item, callback) { log('1.2 enter: ' + memo +', ' + item); setTimeout(function() { @@ -41,7 +47,11 @@ async.reduce(arr, 100, function(memo, item, callback) { // 05.760> 1.2 err: myerr // 05.760> 1.2 result: -//alias: foldr +/** + * 顺序执行从右向左 + * + * alias: foldr + */ async.reduceRight(arr, 100, function(memo, item, callback) { log('1.3 enter: ' + memo +', ' + item); setTimeout(function() { @@ -57,7 +67,9 @@ async.reduceRight(arr, 100, function(memo, item, callback) { // 29.109> 1.3 err: // 29.109> 1.3 result: 109 -// +/** + * 通过t.inc做一个累加器,参与reduce的计算 + */ async.reduce(arr, 100, function(memo,item,callback) { log('1.4 enter: '+memo+','+item); t.inc(item, function(err,n) { @@ -78,6 +90,9 @@ async.reduce(arr, 100, function(memo,item,callback) { // 29.409> 1.4 result: 112 // --> spent 0.62s +/** + * 通过t.inc做一个累加器,并实现对map的结果集做reduce + */ async.map(arr, function(item, callback) { log('1.5 enter: ', item); t.inc(item, function(err,n){ From 46a6ba284ac93172a7485d9b8f9e9a506ccf5e24 Mon Sep 17 00:00:00 2001 From: bsspirit Date: Thu, 12 Sep 2013 11:22:33 +0800 Subject: [PATCH 10/36] 'detect' --- README.md | 3 ++- detect.js | 22 ++++++++++++++++------ 2 files changed, 18 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 6c8124e..f16b4d9 100644 --- a/README.md +++ b/README.md @@ -22,4 +22,5 @@ https://github.com/caolan/async 3. map.js增加mapLimit函数 4. filter_reject.js对注释进行补充 5. filter_reject.js增加rejectSeries函数 -5. reduce.js增加注释 \ No newline at end of file +5. reduce.js增加注释 +6. detect.js增加注释 \ No newline at end of file diff --git a/detect.js b/detect.js index fe2b563..508a59d 100644 --- a/detect.js +++ b/detect.js @@ -3,14 +3,21 @@ var async = require('async'); var t = require('./t'); var log = t.log; -/** - * ȡüĵһԪءΪ˳ִַʽֱӦdetectdetectSeries +/** + * 用于取得集合中满足条件的第一个元素。 + * 它分为并行与顺序执行两种方式,分别对应函数detect和detectSeries。 */ - // detect(array, iterator(item,callback(test)), callback(result) -var arr = [{value:1,delay:500}, - {value:2,delay:200}, - {value:3,delay:300}]; + +var arr = [ + {value:1,delay:500}, + {value:2,delay:200}, + {value:3,delay:300} +]; + +/** + * 并行执行,通过t.inc做一个累加器,得到第一个满足条件的结果对象 + */ async.detect(arr, function(item,callback){ log('1.1 enter: ', item.value); t.inc(item.value, function(err,n) { @@ -29,6 +36,9 @@ async.detect(arr, function(item,callback){ // 10.438> 1.1 handle: 1 // 10.438> 1.1 handle: 1 +/** + * 串行执行,通过t.inc做一个累加器,得到第一个满足条件的结果对象 + */ async.detectSeries(arr, function(item,callback) { log('1.2 enter: ', item.value); t.inc(item.value, function(err,n) { From 51fba3d973ae5efe0f3274114c7ff44408fa728b Mon Sep 17 00:00:00 2001 From: bsspirit Date: Thu, 12 Sep 2013 11:42:18 +0800 Subject: [PATCH 11/36] 'some' --- README.md | 4 +++- some.js | 8 ++++---- sortBy.js | 8 +++++++- 3 files changed, 14 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index f16b4d9..801d4e2 100644 --- a/README.md +++ b/README.md @@ -23,4 +23,6 @@ https://github.com/caolan/async 4. filter_reject.js对注释进行补充 5. filter_reject.js增加rejectSeries函数 5. reduce.js增加注释 -6. detect.js增加注释 \ No newline at end of file +6. detect.js增加注释 +7. sortBy.js增加注释 +8. some.js对注释进行补充 \ No newline at end of file diff --git a/some.js b/some.js index 103485d..b74f53f 100644 --- a/some.js +++ b/some.js @@ -4,7 +4,7 @@ var t = require('./t'); var log = t.log; /** - * ǷһԪʱcallbackõֵΪtrueΪfalse. + * 当集合中是否有至少一个元素满足条件时,最终callback得到的值为true,否则为false. */ // some(arr, iterator(item,callback(test)), callback(result)) //alias: any @@ -12,7 +12,7 @@ var log = t.log; var arr = [1,2,3,6]; /** - * һԪ<=3ԽΪtrue + * 串行执行,集合中至少有一个元素<=3,所以结果为true */ // 1.1 async.some(arr, function(item,callback){ @@ -20,7 +20,7 @@ async.some(arr, function(item,callback){ setTimeout(function(){ log('1.1 handle: ',item); callback(item<=3); - },100); + },100); }, function(result) { log('1.1 result: ', result); }); @@ -36,7 +36,7 @@ async.some(arr, function(item,callback){ /** - * ûһԪ>10ԽΪfalse + * 串行执行,集合中没有一个元素>10,所以结果为false */ async.some(arr, function(item,callback){ log('1.2 enter: ',item); diff --git a/sortBy.js b/sortBy.js index ca44ed1..54ec433 100644 --- a/sortBy.js +++ b/sortBy.js @@ -4,12 +4,15 @@ var t = require('./t'); var log = t.log; /** - * ԼڵԪؽÿԪؽij첽ֵС + * 对集合内的元素进行排序,依据每个元素进行某异步操作后产生的值,从小到大排序。 */ // sortBy(array, iterator(item,callback(err,result)), callback(err,results)) var arr = [3,6,1]; +/** + * 通过异步迭代器,对集合进行排序 + */ async.sortBy(arr, function(item, callback) { setTimeout(function() { callback(null,item); @@ -21,6 +24,9 @@ async.sortBy(arr, function(item, callback) { // 26.562> 1.1 err: null // 26.562> 1.1 results: [ 1, 3, 6 ] +/** + * 迭代出错,callback返回err,没有results + */ async.sortBy(arr, function(item, callback) { setTimeout(function() { if(item===6) callback('myerr'); From 74caddff1400716760d43804a79758bbe82f8b5c Mon Sep 17 00:00:00 2001 From: bsspirit Date: Thu, 12 Sep 2013 11:45:31 +0800 Subject: [PATCH 12/36] 'every' --- README.md | 5 +++-- every.js | 8 ++++---- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 801d4e2..f7ec09d 100644 --- a/README.md +++ b/README.md @@ -20,9 +20,10 @@ 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对注释进行补充 +4. filter_reject.js对注释补充 5. filter_reject.js增加rejectSeries函数 5. reduce.js增加注释 6. detect.js增加注释 7. sortBy.js增加注释 -8. some.js对注释进行补充 \ No newline at end of file +8. some.js对注释补充 +9. every.js对注释补充和修改 diff --git a/every.js b/every.js index f646208..dcceb8e 100644 --- a/every.js +++ b/every.js @@ -4,15 +4,15 @@ var t = require('./t'); var log = t.log; /** - * ÿһԪض򴫸ջصresultΪtrueΪfalse + * 如果集合里每一个元素都满足条件,则传给最终回调的result为true,否则为false */ // every(arr, iterator(item,callback), callback(result)) -//alias: any +//alias: all var arr = [1,2,3,6]; /** - * еԪض<=10Ϊtrue + * 串行执行,集合中所有的元素都<=10,所以为true */ async.every(arr, function(item,callback){ log('1.1 enter: ',item); @@ -34,7 +34,7 @@ async.every(arr, function(item,callback){ // 32.233> 1.1 result: true /** - * һԪز2Ϊfalse + * 串行执行,集合中至少有一个元素不大于2,所以为false */ async.every(arr, function(item,callback){ log('1.2 enter: ',item); From 04c808df1c354e2b25e6e19568474a329c70fea6 Mon Sep 17 00:00:00 2001 From: bsspirit Date: Thu, 12 Sep 2013 11:59:44 +0800 Subject: [PATCH 13/36] 'series' --- README.md | 1 + concat.js | 2 +- series.js | 37 +++++++++++++++++++++---------------- 3 files changed, 23 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index f7ec09d..cf0b5ef 100644 --- a/README.md +++ b/README.md @@ -27,3 +27,4 @@ https://github.com/caolan/async 7. sortBy.js增加注释 8. some.js对注释补充 9. every.js对注释补充和修改 +10. series.js规范调用注释格式 diff --git a/concat.js b/concat.js index cfa9a5e..7bf19d9 100644 --- a/concat.js +++ b/concat.js @@ -4,7 +4,7 @@ var t = require('./t'); var log = t.log; /** - * 将合并多个异步操作的结果合并为一个数组。 + * 将多个异步操作的结果合并为一个数组。 */ // concat(arr, iterator(item,callback(err,result)), callback(err,result)) diff --git a/series.js b/series.js index ee1b1b3..114b899 100644 --- a/series.js +++ b/series.js @@ -1,19 +1,16 @@ var async = require('async'); +var t = require('./t'); +var log = t.log; + /** - * series(tasks, [callback]) - * * 依次执行一个函数数组中的每个函数,每一个函数执行完成之后才能执行下一个函数。 * - * 如果任何一个函数向它的回调函数中传了一个error,则后面的函数都不会被执行,并且将会立刻会将该error以及已经执行了的函数的结果,传给series中最后那个callback。 - * + * 如果任何一个函数向它的回调函数中传了一个error,则后面的函数都不会被执行,并且会立刻将该error以及已经执行了的函数的结果,传给series中最后那个callback。 * 当所有的函数执行完后(没有出错),则会把每个函数传给其回调函数的结果合并为一个数组,传给series最后的那个callback。 - * * 还可以json的形式来提供tasks。每一个属性都会被当作函数来执行,并且结果也会以json形式传给series最后的那个callback。这种方式可读性更高一些。 */ - -var t = require('./t'); -var log = t.log; +// series(tasks, [callback]) /** * 全部函数都正常执行。每个函数产生的值将按顺序合并为一个数组,传给最终的callback。 @@ -24,9 +21,11 @@ async.series([ function(cb) { t.inc(8, cb); }, function(cb) { t.inc(2, cb); } ], function(err, results) { - log('1.1 err: ', err); // -> undefined - log('1.1 results: ', results); // -> [ 4, 9, 3 ] + log('1.1 err: ', err); + log('1.1 results: ', results); }); +//05.155> 1.1 err: null +//05.156> 1.1 results: [ 4, 9, 3 ] /** * 中间有函数出错。出错之后的函数不会执行,错误及之前正常执行的函数结果将传给最终的callback。 @@ -37,9 +36,11 @@ async.series([ function(cb) { t.err('test_err', cb); }, function(cb) { t.inc(8, cb); } ], function (err, results) { - log('1.2 err: ', err); // -> test_err - log('1.2 results: ', results); // -> [ 4, undefined ] + log('1.2 err: ', err); + log('1.2 results: ', results); }); +//04.964> 1.2 err: test_err +//04.973> 1.2 results: [ 4, undefined ] /** * 如果某个函数传的数据是undefined, null, {}, []等,它们会原样传给最终callback。 @@ -53,9 +54,11 @@ async.series([ function(cb) { t.fire([], cb); }, function(cb) { t.fire('abc', cb) } ], function(err, results) { - log('1.3 err: ', err); // -> undefined - log('1.3 results: ', results); // -> [ 3, undefined, null, {}, [], 'abc' ] + log('1.3 err: ', err); + log('1.3 results: ', results); }); +//05.794> 1.3 err: null +//05.795> 1.3 results: [ 3, undefined, null, {}, [], 'abc' ] /** * 以json形式传入tasks。其结果也将以json形式传给最终callback。 @@ -66,6 +69,8 @@ async.series({ c: function (cb) { t.err('myerr', cb); }, d: function (cb) { t.inc(8, cb); } }, function (err, results) { - log('1.4 err: ', err); // -> myerr - log('1.4 results: ', results); // -> { a: 4, b: undefined, c: undefined } + log('1.4 err: ', err); + log('1.4 results: ', results); }); +//05.178> 1.4 err: myerr +//05.179> 1.4 results: { a: 4, b: undefined, c: undefined } \ No newline at end of file From 09a642d66ab090d157ee4a7a0bd30a8d67c2588b Mon Sep 17 00:00:00 2001 From: bsspirit Date: Thu, 12 Sep 2013 12:14:52 +0800 Subject: [PATCH 14/36] 'paralel' --- README.md | 2 ++ parallel.js | 67 ++++++++++++++++++++++++++++++++++++------------- series.js | 2 +- whilst_until.js | 1 - 4 files changed, 52 insertions(+), 20 deletions(-) diff --git a/README.md b/README.md index cf0b5ef..07c7b23 100644 --- a/README.md +++ b/README.md @@ -28,3 +28,5 @@ https://github.com/caolan/async 8. some.js对注释补充 9. every.js对注释补充和修改 10. series.js规范调用注释格式 +11. parallel.js规范调用注释格式 +12. parallel.js增加parallelLimit函数 diff --git a/parallel.js b/parallel.js index bd18df1..9c0c80a 100644 --- a/parallel.js +++ b/parallel.js @@ -1,17 +1,15 @@ var async = require('async'); +var t = require('./t'); +var log = t.log; /** * 并行执行多个函数,每个函数都是立即执行,不需要等待其它函数先执行。传给最终callback的数组中的数据按照tasks中声明的顺序,而不是执行完成的顺序。 * * 如果某个函数出错,则立刻将err和已经执行完的函数的结果值传给parallel最终的callback。其它未执行完的函数的值不会传到最终数据,但要占个位置。 - * * 同时支持json形式的tasks,其最终callback的结果也为json形式。 */ // parallel(tasks, [callback]) -var t = require('./t'); -var log = t.log; - /** * 并行执行多个函数,每个函数的值将按函数声明的先后顺序汇成一个数组,传给最终callback。 */ @@ -21,44 +19,77 @@ async.parallel([ function(cb) { t.fire('a200', cb, 200) }, function(cb) { t.fire('a300', cb, 300) } ], function (err, results) { - log('1.1 err: ', err); // -> undefined - log('1.1 results: ', results); // ->[ 'a400', 'a200', 'a300' ] + log('1.1 err: ', err); + log('1.1 results: ', results); }); +//36.929> 1.1 err: null +//36.930> 1.1 results: [ 'a400', 'a200', 'a300' ] /** - * 如果中途有个函数出错,则将该err和已经完成的函数值汇成一个数组,传给最终的callback。还没有执行完的函数的值将被忽略,但要在最终数组中占个位置 - */ +* 如果中途有个函数出错,则将该err和已经完成的函数值汇成一个数组,传给最终的callback。还没有执行完的函数的值将被忽略,但要在最终数组中占个位置 +*/ // 1.2 async.parallel([ function(cb) { log('1.2.1: ', 'start'); t.fire('a400', cb, 400) }, // 该函数的值不会传给最终callback,但要占个位置 function(cb) { log('1.2.2: ', 'start'); t.err('e200', cb, 200) }, function(cb) { log('1.2.3: ', 'start'); t.fire('a100', cb, 100) } ], function(err, results) { - log('1.2 err: ', err); // -> e200 - log('1.2 results: ', results); // -> [ , undefined, 'a100' ] + log('1.2 err: ', err); + log('1.2 results: ', results); }); +//36.537> 1.2.1: start +//36.540> 1.2.2: start +//36.541> 1.2.3: start +//36.741> 1.2 err: e200 +//36.744> 1.2 results: [ , undefined, 'a100' ] /** - * 以json形式传入tasks,最终results也为json - */ +* 以json形式传入tasks,最终results也为json +*/ // 1.3 async.parallel({ a: function(cb) { t.fire('a400', cb, 400) }, b: function(cb) { t.fire('c300', cb, 300) } }, function(err, results) { - log('1.3 err: ', err); // -> undefined - log('1.3 results: ', results); // -> { b: 'c300', a: 'a400' } + log('1.3 err: ', err); + log('1.3 results: ', results); }); +//36.943> 1.3 err: null +//36.944> 1.3 results: { b: 'c300', a: 'a400' } /** - * 如果中途出错,会将err与已经完成的函数值(汇成一个json)传给最终callback。未执行完成的函数值被忽略,不会出现在最终json中。 - */ +* 如果中途出错,会将err与已经完成的函数值(汇成一个json)传给最终callback。未执行完成的函数值被忽略,不会出现在最终json中。 +*/ // 1.4 async.parallel({ a: function(cb) { t.fire('a400', cb, 400) }, // 该函数的值不会传给最终的callback b: function(cb) { t.err('e300', cb, 300) }, c: function(cb) { t.fire('c200', cb, 200) } }, function(err, results) { - log('1.4 err: ', err); // -> e300 - log('1.4 results: ', results); // -> { c: 'c200', b: undefined } + log('1.4 err: ', err); + log('1.4 results: ', results); +}); +//36.853> 1.4 err: e300 +//36.854> 1.4 results: { c: 'c200', b: undefined } + +/** + * 并行执行,同时最多2个函数并行,传给最终callback。 + */ +//1.5 +async.parallelLimit({ + a:function(cb) { log('a start'); t.fire('a400', cb, 200) }, + b:function(cb) { log('b start'); t.fire('b200', cb, 200) }, + c:function(cb) { log('c start'); t.fire('c100', cb, 100) }, + d:function(cb) { log('d start'); t.fire('d600', cb, 600) }, + e:function(cb) { log('e start'); t.fire('e300', cb, 300) } +},2, function(err, results) { + log('1.5 err: ', err); + log('1.5 results: ', results); }); +//26.993> a start +//26.996> b start +//27.200> c start +//27.202> d start +//27.313> e start +//27.809> 1.5 err: +//27.810> 1.5 results: { a: 'a400', b: 'b200', c: 'c100', e: 'e300', d: 'd600' } \ No newline at end of file diff --git a/series.js b/series.js index 114b899..5718f85 100644 --- a/series.js +++ b/series.js @@ -4,7 +4,7 @@ var t = require('./t'); var log = t.log; /** - * 依次执行一个函数数组中的每个函数,每一个函数执行完成之后才能执行下一个函数。 + * 串行执行,一个函数数组中的每个函数,每一个函数执行完成之后才能执行下一个函数。 * * 如果任何一个函数向它的回调函数中传了一个error,则后面的函数都不会被执行,并且会立刻将该error以及已经执行了的函数的结果,传给series中最后那个callback。 * 当所有的函数执行完后(没有出错),则会把每个函数传给其回调函数的结果合并为一个数组,传给series最后的那个callback。 diff --git a/whilst_until.js b/whilst_until.js index 3dd933d..3321f77 100644 --- a/whilst_until.js +++ b/whilst_until.js @@ -22,7 +22,6 @@ var log = t.log; */ // whilst(test, fn, callback) - /** * 正常情况,没有出错。第二个函数虽然是异步调用,但被同步执行。所以第三个函数被调用时,已经过了3秒。 */ From 5ea284546ef70f810267e5d6e97740f56324ca73 Mon Sep 17 00:00:00 2001 From: bsspirit Date: Thu, 12 Sep 2013 14:34:28 +0800 Subject: [PATCH 15/36] 'whilist,until' --- README.md | 7 ++- whilst_until.js | 110 +++++++++++++++++++++++++++++++++++++++--------- 2 files changed, 95 insertions(+), 22 deletions(-) diff --git a/README.md b/README.md index 07c7b23..16aad0a 100644 --- a/README.md +++ b/README.md @@ -27,6 +27,9 @@ https://github.com/caolan/async 7. sortBy.js增加注释 8. some.js对注释补充 9. every.js对注释补充和修改 -10. series.js规范调用注释格式 -11. parallel.js规范调用注释格式 +10. series.js调整注释格式 +11. parallel.js调整注释格式 12. parallel.js增加parallelLimit函数 +13. whilist_until.js调整注释格式 +14. whilist_until.js增加doWhilst函数 +15. whilist_until.js增加doUntil函数 diff --git a/whilst_until.js b/whilst_until.js index 3321f77..d36cbe2 100644 --- a/whilst_until.js +++ b/whilst_until.js @@ -18,13 +18,12 @@ var log = t.log; * 该函数的功能比较简单,条件变量通常定义在外面,可供每个函数访问。在循环中,异步调用时产生的值实际上被丢弃了,因为最后那个callback只能传入错误信息。 * * 另外,第二个函数fn需要能接受一个函数cb,这个cb最终必须被执行,用于表示出错或正常结束。 - * */ // whilst(test, fn, callback) /** - * 正常情况,没有出错。第二个函数虽然是异步调用,但被同步执行。所以第三个函数被调用时,已经过了3秒。 - */ +* 正常情况,没有出错。第二个函数虽然是异步调用,但被同步执行。所以第三个函数被调用时,已经过了3秒。 +*/ // 1.1 var count1 = 0; async.whilst( @@ -36,13 +35,18 @@ async.whilst( }, function(err) { // 3s have passed - log('1.1 err: ', err); // -> undefined + log('1.1 err: ', err); } ); +//10.318> 1.1 count: 0 +//11.330> 1.1 count: 1 +//12.342> 1.1 count: 2 +//13.356> 1.1 err: + /** - * 中途出错。出错后立刻调用第三个函数。 - */ +* 中途出错。出错后立刻调用第三个函数。 +*/ // 1.2 var count2 = 0; async.whilst( @@ -58,41 +62,107 @@ async.whilst( }, function(err) { // 2s have passed - log('1.2 err: ', err); // -> myerr + log('1.2 err: ', err); } ); +//12.805> 1.2 count: 0 +//13.824> 1.2 count: 1 +//14.026> 1.2 err: myerr /** - * 第二个函数即使产生值,也会被忽略。第三个函数只能得到err。 - */ +* 第二个函数即使产生值,也会被忽略。第三个函数只能得到err。 +*/ // 1.3 var count3 = 0; async.whilst( - function() { return count3 < 3 }, + function() {return count3 < 3 }, function(cb) { log('1.3 count: ', count3); t.inc(count3++, cb); }, function(err,result){ // result没有用 - log('1.3 err: ', err); // -> undefined - log('1.3 result: ', result); // -> undefined + log('1.3 err: ', err); + log('1.3 result: ', result); } ); +//45.311> 1.3 count: 0 +//45.514> 1.3 count: 1 +//45.718> 1.3 count: 2 +//45.920> 1.3 err: +//45.923> 1.3 result: /** - * until与whilst正好相反,当test为false时循环,与true时跳出。其它特性一致。 - */ -// 1.4 +* doWhilst交换了fn,test的参数位置,先执行一次循环,再做test判断。 和javascript中do..while语法一致。 +*/ +// doWhilst(fn, test, callback) +//1.4 var count4 = 0; -async.until( - function() { return count4>3 }, +async.doWhilst( function(cb) { log('1.4 count: ', count4); - count4++; + t.inc(count4++, cb); + }, + function() { log("1.4 test"); return count4 < 3 }, + function(err,result){ // result没有用 + log('1.4 err: ', err); + log('1.4 result: ', result); + } +); +//33.643> 1.4 count: 0 +//33.848> 1.4 test +//33.850> 1.4 count: 1 +//34.054> 1.4 test +//34.057> 1.4 count: 2 +//34.269> 1.4 test +//34.270> 1.4 err: +//34.270> 1.4 result: + +/** +* until与whilst正好相反,当test为false时循环,与true时跳出。其它特性一致。 +*/ +// 1.5 +var count5 = 0; +async.until( + function() { return count5>3 }, + function(cb) { + log('1.5 count: ', count5); + count5++; + setTimeout(cb, 200); + }, + function(err) { + // 4s have passed + log('1.5 err: ',err); + } +); +//42.498> 1.5 count: 0 +//42.701> 1.5 count: 1 +//42.905> 1.5 count: 2 +//43.107> 1.5 count: 3 +//43.313> 1.5 err: + +/** +* doUntil与doWhilst正好相反,当test为false时循环,与true时跳出。其它特性一致。 +*/ +// 1.6 +var count6 = 0; +async.doUntil( + function(cb) { + log('1.6 count: ', count6); + count6++; setTimeout(cb, 200); }, + function() { log('1.6 test');return count6>3 }, function(err) { // 4s have passed - log('1.4 err: ',err); // -> undefined + log('1.6 err: ',err); } -); \ No newline at end of file +); +//41.831> 1.6 count: 0 +//42.035> 1.6 test +//42.037> 1.6 count: 1 +//42.241> 1.6 test +//42.244> 1.6 count: 2 +//42.456> 1.6 test +//42.457> 1.6 count: 3 +//42.660> 1.6 test +//42.661> 1.6 err: \ No newline at end of file From 3f239bcf1b6c327a94a663b90bf267a63e3aeb89 Mon Sep 17 00:00:00 2001 From: bsspirit Date: Thu, 12 Sep 2013 14:38:50 +0800 Subject: [PATCH 16/36] 'forever' --- README.md | 1 + whilst_until.js | 305 ++++++++++++++++++++++++++---------------------- 2 files changed, 169 insertions(+), 137 deletions(-) diff --git a/README.md b/README.md index 16aad0a..d196f5a 100644 --- a/README.md +++ b/README.md @@ -33,3 +33,4 @@ https://github.com/caolan/async 13. whilist_until.js调整注释格式 14. whilist_until.js增加doWhilst函数 15. whilist_until.js增加doUntil函数 +16. whilist_until.js增加forever函数 diff --git a/whilst_until.js b/whilst_until.js index d36cbe2..e1169be 100644 --- a/whilst_until.js +++ b/whilst_until.js @@ -21,148 +21,179 @@ var log = t.log; */ // whilst(test, fn, callback) -/** -* 正常情况,没有出错。第二个函数虽然是异步调用,但被同步执行。所以第三个函数被调用时,已经过了3秒。 -*/ -// 1.1 -var count1 = 0; -async.whilst( - function() { return count1 < 3 }, - function(cb) { - log('1.1 count: ', count1); - count1++; - setTimeout(cb, 1000); - }, - function(err) { - // 3s have passed - log('1.1 err: ', err); - } -); -//10.318> 1.1 count: 0 -//11.330> 1.1 count: 1 -//12.342> 1.1 count: 2 -//13.356> 1.1 err: - - -/** -* 中途出错。出错后立刻调用第三个函数。 -*/ -// 1.2 -var count2 = 0; -async.whilst( - function() { return count2 < 3 }, - function(cb) { - log('1.2 count: ', count2); - if(count2===1) { - t.err('myerr', cb, 200); - } else { - count2++; - setTimeout(cb, 1000); - } - }, - function(err) { - // 2s have passed - log('1.2 err: ', err); - } -); -//12.805> 1.2 count: 0 -//13.824> 1.2 count: 1 -//14.026> 1.2 err: myerr +///** +//* 正常情况,没有出错。第二个函数虽然是异步调用,但被同步执行。所以第三个函数被调用时,已经过了3秒。 +//*/ +//// 1.1 +//var count1 = 0; +//async.whilst( +// function() { return count1 < 3 }, +// function(cb) { +// log('1.1 count: ', count1); +// count1++; +// setTimeout(cb, 1000); +// }, +// function(err) { +// // 3s have passed +// log('1.1 err: ', err); +// } +//); +////10.318> 1.1 count: 0 +////11.330> 1.1 count: 1 +////12.342> 1.1 count: 2 +////13.356> 1.1 err: +// +// +///** +//* 中途出错。出错后立刻调用第三个函数。 +//*/ +//// 1.2 +//var count2 = 0; +//async.whilst( +// function() { return count2 < 3 }, +// function(cb) { +// log('1.2 count: ', count2); +// if(count2===1) { +// t.err('myerr', cb, 200); +// } else { +// count2++; +// setTimeout(cb, 1000); +// } +// }, +// function(err) { +// // 2s have passed +// log('1.2 err: ', err); +// } +//); +////12.805> 1.2 count: 0 +////13.824> 1.2 count: 1 +////14.026> 1.2 err: myerr +// +///** +//* 第二个函数即使产生值,也会被忽略。第三个函数只能得到err。 +//*/ +//// 1.3 +//var count3 = 0; +//async.whilst( +// function() {return count3 < 3 }, +// function(cb) { +// log('1.3 count: ', count3); +// t.inc(count3++, cb); +// }, +// function(err,result){ // result没有用 +// log('1.3 err: ', err); +// log('1.3 result: ', result); +// } +//); +////45.311> 1.3 count: 0 +////45.514> 1.3 count: 1 +////45.718> 1.3 count: 2 +////45.920> 1.3 err: +////45.923> 1.3 result: +// +///** +//* doWhilst交换了fn,test的参数位置,先执行一次循环,再做test判断。 和javascript中do..while语法一致。 +//*/ +//// doWhilst(fn, test, callback) +////1.4 +//var count4 = 0; +//async.doWhilst( +// function(cb) { +// log('1.4 count: ', count4); +// t.inc(count4++, cb); +// }, +// function() { log("1.4 test"); return count4 < 3 }, +// function(err,result){ // result没有用 +// log('1.4 err: ', err); +// log('1.4 result: ', result); +// } +//); +////33.643> 1.4 count: 0 +////33.848> 1.4 test +////33.850> 1.4 count: 1 +////34.054> 1.4 test +////34.057> 1.4 count: 2 +////34.269> 1.4 test +////34.270> 1.4 err: +////34.270> 1.4 result: +// +///** +//* until与whilst正好相反,当test为false时循环,与true时跳出。其它特性一致。 +//*/ +//// 1.5 +//var count5 = 0; +//async.until( +// function() { return count5>3 }, +// function(cb) { +// log('1.5 count: ', count5); +// count5++; +// setTimeout(cb, 200); +// }, +// function(err) { +// // 4s have passed +// log('1.5 err: ',err); +// } +//); +////42.498> 1.5 count: 0 +////42.701> 1.5 count: 1 +////42.905> 1.5 count: 2 +////43.107> 1.5 count: 3 +////43.313> 1.5 err: +// +///** +//* doUntil与doWhilst正好相反,当test为false时循环,与true时跳出。其它特性一致。 +//*/ +//// doUntil(fn, test, callback) +//// 1.6 +//var count6 = 0; +//async.doUntil( +// function(cb) { +// log('1.6 count: ', count6); +// count6++; +// setTimeout(cb, 200); +// }, +// function() { log('1.6 test');return count6>3 }, +// function(err) { +// // 4s have passed +// log('1.6 err: ',err); +// } +//); +////41.831> 1.6 count: 0 +////42.035> 1.6 test +////42.037> 1.6 count: 1 +////42.241> 1.6 test +////42.244> 1.6 count: 2 +////42.456> 1.6 test +////42.457> 1.6 count: 3 +////42.660> 1.6 test +////42.661> 1.6 err: /** -* 第二个函数即使产生值,也会被忽略。第三个函数只能得到err。 -*/ -// 1.3 -var count3 = 0; -async.whilst( - function() {return count3 < 3 }, - function(cb) { - log('1.3 count: ', count3); - t.inc(count3++, cb); - }, - function(err,result){ // result没有用 - log('1.3 err: ', err); - log('1.3 result: ', result); - } -); -//45.311> 1.3 count: 0 -//45.514> 1.3 count: 1 -//45.718> 1.3 count: 2 -//45.920> 1.3 err: -//45.923> 1.3 result: - -/** -* doWhilst交换了fn,test的参数位置,先执行一次循环,再做test判断。 和javascript中do..while语法一致。 -*/ -// doWhilst(fn, test, callback) -//1.4 -var count4 = 0; -async.doWhilst( - function(cb) { - log('1.4 count: ', count4); - t.inc(count4++, cb); - }, - function() { log("1.4 test"); return count4 < 3 }, - function(err,result){ // result没有用 - log('1.4 err: ', err); - log('1.4 result: ', result); - } -); -//33.643> 1.4 count: 0 -//33.848> 1.4 test -//33.850> 1.4 count: 1 -//34.054> 1.4 test -//34.057> 1.4 count: 2 -//34.269> 1.4 test -//34.270> 1.4 err: -//34.270> 1.4 result: - -/** -* until与whilst正好相反,当test为false时循环,与true时跳出。其它特性一致。 -*/ -// 1.5 -var count5 = 0; -async.until( - function() { return count5>3 }, - function(cb) { - log('1.5 count: ', count5); - count5++; - setTimeout(cb, 200); - }, - function(err) { - // 4s have passed - log('1.5 err: ',err); - } -); -//42.498> 1.5 count: 0 -//42.701> 1.5 count: 1 -//42.905> 1.5 count: 2 -//43.107> 1.5 count: 3 -//43.313> 1.5 err: - -/** -* doUntil与doWhilst正好相反,当test为false时循环,与true时跳出。其它特性一致。 -*/ -// 1.6 -var count6 = 0; -async.doUntil( + * forever,无论条件循环执行,如果不出错,callback永远不被执行 + */ +//forever(fn, callback) +//1.7 +var count7 = 0; +async.forever( function(cb) { - log('1.6 count: ', count6); - count6++; + log('1.7 count: ', count7); + count7++; setTimeout(cb, 200); }, - function() { log('1.6 test');return count6>3 }, function(err) { - // 4s have passed - log('1.6 err: ',err); + log('1.7 err: ',err); } ); -//41.831> 1.6 count: 0 -//42.035> 1.6 test -//42.037> 1.6 count: 1 -//42.241> 1.6 test -//42.244> 1.6 count: 2 -//42.456> 1.6 test -//42.457> 1.6 count: 3 -//42.660> 1.6 test -//42.661> 1.6 err: \ No newline at end of file +//52.770> 1.7 count: 0 +//52.973> 1.7 count: 1 +//53.175> 1.7 count: 2 +//53.377> 1.7 count: 3 +//53.583> 1.7 count: 4 +//53.785> 1.7 count: 5 +//53.987> 1.7 count: 6 +//54.189> 1.7 count: 7 +//54.391> 1.7 count: 8 +//54.593> 1.7 count: 9 +//54.795> 1.7 count: 10 +//54.997> 1.7 count: 11 +//55.199> 1.7 count: 12 \ No newline at end of file From 1373c22250725f19dc10f77c77e3c7939fbca9c7 Mon Sep 17 00:00:00 2001 From: bsspirit Date: Thu, 12 Sep 2013 14:43:56 +0800 Subject: [PATCH 17/36] 'waterfall' --- README.md | 2 ++ waterfall.js | 43 +++++++++++++++++++++++++++---------------- 2 files changed, 29 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index d196f5a..d96da6b 100644 --- a/README.md +++ b/README.md @@ -34,3 +34,5 @@ https://github.com/caolan/async 14. whilist_until.js增加doWhilst函数 15. whilist_until.js增加doUntil函数 16. whilist_until.js增加forever函数 +17. waterfall.js调整注释格式 + diff --git a/waterfall.js b/waterfall.js index 0acf550..e6ef0b4 100644 --- a/waterfall.js +++ b/waterfall.js @@ -1,7 +1,10 @@ var async = require('async'); +var t = require('./t'); +var log = t.log; /** - * 按顺序依次执行一组函数。每个函数产生的值,都将传给下一个。如果中途出错,后面的函数将不会被执行。错误信息将传给waterfall最终的callback。之前产生的结果被丢弃。 + * 按顺序依次执行一组函数。每个函数产生的值,都将传给下一个。 + * 如果中途出错,后面的函数将不会被执行。错误信息将传给waterfall最终的callback。之前产生的结果被丢弃。 * * 这个函数名为waterfall(瀑布),可以想像瀑布从上到下,中途冲过一层层突起的石头。 * @@ -9,9 +12,6 @@ var async = require('async'); */ // async.waterfall(tasks, [callback]); -var t = require('./t'); -var log = t.log; - /** * 所有函数正常执行,每个函数的结果都将变为下一个函数的参数。 * @@ -23,33 +23,44 @@ async.waterfall([ function(n, cb) { log('1.1.2: ',n); t.inc(n, cb); }, function(n, cb) { log('1.1.3: ',n); t.fire(n*n, cb); } ], function (err, result) { - log('1.1 err: ', err); // -> null - log('1.1 result: ', result); // -> 16 + log('1.1 err: ', err); + log('1.1 result: ', result); }); +//31.749> 1.1.1: start +//31.752> 1.1.2: 3 +//31.953> 1.1.3: 4 +//32.156> 1.1 err: null +//32.159> 1.1 result: 16 /** - * 中途有函数出错,其err直接传给最终callback,结果被丢弃,后面的函数不再执行。 - */ +* 中途有函数出错,其err直接传给最终callback,结果被丢弃,后面的函数不再执行。 +*/ // 1.2 async.waterfall([ function(cb) { log('1.2.1: ', 'start'); cb(null, 3); }, function(n, cb) { log('1.2.2: ', n); t.inc(n, cb); }, function(n, cb) { log('1.2.3: ', n); t.err('myerr', cb); }, - function(n, cb) { log('1.2.4: ', n); t.fire(n, cb); } + function(n, cb) { log('1.2.4: ', n); t.fire(n, cb); } ], function (err, result) { - log('1.2 err: ', err); // -> myerr - log('1.2 result: ', result); // -> undefined + log('1.2 err: ', err); + log('1.2 result: ', result); }); +//44.935> 1.2.1: start +//44.939> 1.2.2: 3 +//45.140> 1.2.3: 4 +//45.344> 1.2 err: myerr +//45.348> 1.2 result: /** - * 注意: 以json形式传入tasks,将不会被执行!! - */ +* 注意: 以json形式传入tasks,将不会被执行!! +*/ async.waterfall({ - // these tasks won't be invoked a: function(cb) { log('1.3.1: ', 'start'); cb(null, 3); }, b: function(n, cb) { log('1.3.2: ', n); t.inc(n, cb); }, c: function(n, cb) { log('1.3.3: ', n); t.fire(n*n, cb); } }, function (err, result) { - log('1.3 err: ', err); // -> undefined - log('1.3 result: ', result); // -> undefined + log('1.3 err: ', err); + log('1.3 result: ', result); }); +//49.222> 1.3 err: [Error: First argument to waterfall must be an array of functions] +//49.228> 1.3 result: \ No newline at end of file From d09c18df6ff023c71c53a2f87ac91265f9e5122c Mon Sep 17 00:00:00 2001 From: bsspirit Date: Thu, 12 Sep 2013 15:30:41 +0800 Subject: [PATCH 18/36] 'apply' --- README.md | 3 +++ apply.js | 30 +++++++++++++++++++++++------- compose.js | 42 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 68 insertions(+), 7 deletions(-) create mode 100644 compose.js diff --git a/README.md b/README.md index d96da6b..000df06 100644 --- a/README.md +++ b/README.md @@ -35,4 +35,7 @@ https://github.com/caolan/async 15. whilist_until.js增加doUntil函数 16. whilist_until.js增加forever函数 17. waterfall.js调整注释格式 +18. 增加compose.js文件 +19. apply.js补充注释并增加一个实例 + diff --git a/apply.js b/apply.js index a9663fc..6800f4c 100644 --- a/apply.js +++ b/apply.js @@ -4,7 +4,7 @@ var t = require('./t'); var log = t.log; /** - * async.apply是一个非常好用的函数,可以让我们给一个函数预绑定多个参数并生成一个可直接调用的新函数,简化代码。 + * apply是一个非常好用的函数,可以让我们给一个函数预绑定多个参数并生成一个可直接调用的新函数,简化代码。 * * function(callback) { t.inc(3, callback); } * 等价于: @@ -12,16 +12,32 @@ var log = t.log; */ // 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; + 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 \ No newline at end of file diff --git a/compose.js b/compose.js new file mode 100644 index 0000000..ead9503 --- /dev/null +++ b/compose.js @@ -0,0 +1,42 @@ +var async = require('async'); +var t = require('./t'); +var log = t.log; + +/** + * 创建一个包括一组异步函数的函数集合,每个函数会消费上一次函数的返回值。 + * 把f(),g(),h()异步函数,组合成f(g(h()))的形式,通过callback得到返回值。 + */ +// compose(fn1, fn2...) + +/** + * 通过compose组合,f(g(h()))的形式,从内层到外层的执行的顺序。 + */ +//1.1 +function f(n,callback){ + log('1.1.f enter: ',n); + setTimeout(function () { + callback(null, n + 1); + }, 10); +} +function g(n, callback) { + log('1.1.g enter: ',n); + setTimeout(function () { + callback(null, n * 2); + }, 10); +} +function h(n, callback) { + log('1.1.h enter: ',n); + setTimeout(function () { + callback(null, n - 10); + }, 10); +} +var fgh = async.compose(f,g,h); +fgh(4,function(err,result){ + log('1.1 err: ', err); + log('1.1 result: ', result); +}); +//05.307> 1.1.h enter: 4 +//05.329> 1.1.g enter: -6 +//05.341> 1.1.f enter: -12 +//05.361> 1.1 err: null +//05.362> 1.1 result: -11 \ No newline at end of file From 4ed25b54ec3cbadd4700b6c7fc2ddd242862db9a Mon Sep 17 00:00:00 2001 From: bsspirit Date: Thu, 12 Sep 2013 15:42:19 +0800 Subject: [PATCH 19/36] 'nextTick' --- README.md | 31 ++++++++++++++++--------------- nextTick.js | 18 ++++++++++++------ 2 files changed, 28 insertions(+), 21 deletions(-) diff --git a/README.md b/README.md index 000df06..6711757 100644 --- a/README.md +++ b/README.md @@ -22,20 +22,21 @@ https://github.com/caolan/async 3. map.js增加mapLimit函数 4. filter_reject.js对注释补充 5. filter_reject.js增加rejectSeries函数 -5. reduce.js增加注释 -6. detect.js增加注释 -7. sortBy.js增加注释 -8. some.js对注释补充 -9. every.js对注释补充和修改 -10. series.js调整注释格式 -11. parallel.js调整注释格式 -12. parallel.js增加parallelLimit函数 -13. whilist_until.js调整注释格式 -14. whilist_until.js增加doWhilst函数 -15. whilist_until.js增加doUntil函数 -16. whilist_until.js增加forever函数 -17. waterfall.js调整注释格式 -18. 增加compose.js文件 -19. apply.js补充注释并增加一个实例 +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实例 diff --git a/nextTick.js b/nextTick.js index 3532e37..b8bd8e2 100644 --- a/nextTick.js +++ b/nextTick.js @@ -1,20 +1,26 @@ var async = require('async'); +var t = require('./t'); +var log = t.log; /** - * async.nextTick的作用与nodejs的nextTick一样,都是把某个函数调用放在队列的尾部。但在浏览器端,只能使用setTimeout(callback,0),但这个方法有时候会让其它高优先级的任务插到前面去。 - * + * nextTick的作用与nodejs的nextTick一样,再最后调用函数。 + * 但在浏览器端,只能使用setTimeout(callback,0),但这个方法有时候会让其它高优先级的任务插到前面去。 * 所以提供了这个nextTick,让同样的代码在服务器端和浏览器端表现一致。 */ // nextTick(callback) var calls = []; - async.nextTick(function() { calls.push('two'); }); - +async.nextTick(function() { + log('1.1',calls); +}); calls.push('one'); - +log('1.2',calls); async.nextTick(function() { - console.log(calls); // -> [ 'one', 'two' ] + log('1.3',calls); }); +//09.838> 1.2[ 'one' ] +//09.842> 1.1[ 'one', 'two' ] +//09.843> 1.3[ 'one', 'two' ] From 2e5e596b1128042fa28d6cc142147ee14bbd530f Mon Sep 17 00:00:00 2001 From: bsspirit Date: Thu, 12 Sep 2013 16:07:30 +0800 Subject: [PATCH 20/36] 'times_timesSeries' --- README.md | 1 + times.js | 75 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 76 insertions(+) create mode 100644 times.js diff --git a/README.md b/README.md index 6711757..f9aa22b 100644 --- a/README.md +++ b/README.md @@ -38,5 +38,6 @@ https://github.com/caolan/async 19. 增加compose.js文件 20. apply.js补充注释并增加一个实例 21. 修改nextTick.js实例 +22. 增加times.js文件,包括times和timesSeries函数 diff --git a/times.js b/times.js new file mode 100644 index 0000000..80b7365 --- /dev/null +++ b/times.js @@ -0,0 +1,75 @@ +var async = require('async'); +var t = require('./t'); +var log = t.log; + +/** +* 异步运行,times可以指定调用几次,并把结果合并到数组中返回 +*/ +// times(n, callback) + +function delay(n){return (n+12) % 7 *100;} +var createUser = function(id, callback) { + callback(null, { + id: 'user' + id, + delay:delay(id) + }) +} + +/** + * 异步执行,调用3次createUser函数,结果被合并到数组返回 + */ +//1.1 +async.times(3, function(n, callback){ + log("1.1 enter: "+ n); + setTimeout(function(){ + log('1.1 handler: ',n); + createUser(n, function(err, user) { + callback(err, user) + }) + },delay(n)); +}, function(err, users) { + log('1.1 err: ',err); + log('1.1 result: ',users); +}); +//07.397> 1.1 enter: 0 +//07.400> 1.1 enter: 1 +//07.401> 1.1 enter: 2 +//07.412> 1.1 handler: 2 +//07.912> 1.1 handler: 0 +//08.009> 1.1 handler: 1 +//08.010> 1.1 err: null +//08.011> 1.1 result: [ { id: 'user0', delay: 500 }, +// { id: 'user1', delay: 600 }, +// { id: 'user2', delay: 0 } ] + +/** +* 与time唯一不同的是同步执行 +*/ +//timesSeries(n, callback) + +/** + * 同步执行,调用3次createUser函数,结果被合并到数组返回 + */ +//1.2 +async.timesSeries(3, function(n, callback){ + log("1.2 enter: "+ n); + setTimeout(function(){ + log('1.2 handler: ',n); + createUser(n, function(err, user) { + callback(err, user) + }) + },delay(n)); +}, function(err, users) { + log('1.2 err: ',err); + log('1.2 result: ',users); +}); +//16.642> 1.2 enter: 0 +//17.159> 1.2 handler: 0 +//17.162> 1.2 enter: 1 +//17.763> 1.2 handler: 1 +//17.767> 1.2 enter: 2 +//17.778> 1.2 handler: 2 +//17.779> 1.2 err: null +//17.780> 1.2 result: [ { id: 'user0', delay: 500 }, +// { id: 'user1', delay: 600 }, +// { id: 'user2', delay: 0 } ] \ No newline at end of file From 6bb157b796583840388de3bfddb342aabde97b2f Mon Sep 17 00:00:00 2001 From: bsspirit Date: Thu, 12 Sep 2013 16:21:44 +0800 Subject: [PATCH 21/36] 'iterator' --- README.md | 1 + iterator.js | 72 +++++++++++++++++++++++++++++++++++------------------ times.js | 2 +- 3 files changed, 50 insertions(+), 25 deletions(-) diff --git a/README.md b/README.md index f9aa22b..a8410c3 100644 --- a/README.md +++ b/README.md @@ -39,5 +39,6 @@ https://github.com/caolan/async 20. apply.js补充注释并增加一个实例 21. 修改nextTick.js实例 22. 增加times.js文件,包括times和timesSeries函数 +23. 修改iterator.js实例 diff --git a/iterator.js b/iterator.js index a2c2be2..53084fd 100644 --- a/iterator.js +++ b/iterator.js @@ -1,5 +1,4 @@ var async = require('async'); - var t = require('./t'); var log = t.log; @@ -11,33 +10,58 @@ var log = t.log; // async.iterator(tasks) var iter = async.iterator([ - function() { console.log('I am 111') }, - function() { console.log('I am 222') }, - function() { console.log('I am 333') } + function () { + log('I am 111') + }, + function () { + log('I am 222') + }, + function () { + log('I am 333') + } ]); -// 直接调用(),会执行当前函数,并返回一个由下个函数为起点的新的iterator -console.log('------- iter() ---------'); -var it1 = iter(); // => 'I am 111' -it1(); // => 'I am 222' -it1(); // => 'I am 222' -it1(); // => 'I am 222' - -console.log('----'); +/** +* 直接调用(),会执行当前函数,并返回一个由下个函数为起点的新的iterator +*/ +//1.1 +log('1.1 iter()'); +var it1 = iter(); +it1(); +it1(); +//28.368> 1.1 iter() +//28.371> I am 111 +//28.372> I am 222 +//28.372> I am 222 -var it2 = iter(); // => 'I am 111' -var it3 = it2(); // => 'I am 222' -var it4 = it3(); // => 'I am 333' -// it4(); // 这句代码执行会报错 -console.log(it4); // => 'null' +/** +* 通过iter()来调用下一个函数 +*/ +log('1.2 iter()'); +var it2 = iter(); +var it3 = it2(); +var it4 = it3(); +//it4(); // 这句代码执行会报错 +log(it4); // => 'null' +//32.449> 1.2 iter() +//32.452> I am 111 +//32.452> I am 222 +//32.453> I am 333 +//32.454> null -// 调用next(),不会执行当前函数,直接返回由下个函数为起点的新iterator -// 对于同一个iterator,多次调用next(),不会影响自己 -console.log('-------- iter.next() -------'); +/** + * 调用next(),不会执行当前函数,直接返回由下个函数为起点的新iterator + * 对于同一个iterator,多次调用next(),不会影响自己 + */ +//1.3 +log('1.3 iter()'); var it5 = iter.next(); -it5(); // => 'I am 222' +it5(); var it6 = iter.next().next(); -it6(); // => 'I am 333' -iter(); // => 'I am 111' - +it6(); +iter(); +//39.895> 1.3 iter() +//39.898> I am 222 +//39.899> I am 333 +//39.899> I am 111 diff --git a/times.js b/times.js index 80b7365..dc9d072 100644 --- a/times.js +++ b/times.js @@ -43,7 +43,7 @@ async.times(3, function(n, callback){ // { id: 'user2', delay: 0 } ] /** -* 与time唯一不同的是同步执行 +* timesSeries与time唯一不同的是,同步执行 */ //timesSeries(n, callback) From d55aefb26cee2d112ba254e8c51de5c3380019a1 Mon Sep 17 00:00:00 2001 From: bsspirit Date: Thu, 12 Sep 2013 16:32:59 +0800 Subject: [PATCH 22/36] 'auto' --- README.md | 1 + auto.js | 98 ++++++++++++++++++++++++++++++----------------------- iterator.js | 12 ++----- 3 files changed, 59 insertions(+), 52 deletions(-) diff --git a/README.md b/README.md index a8410c3..26ca5d1 100644 --- a/README.md +++ b/README.md @@ -40,5 +40,6 @@ https://github.com/caolan/async 21. 修改nextTick.js实例 22. 增加times.js文件,包括times和timesSeries函数 23. 修改iterator.js实例 +24. 修正auto.js关于第二个实例的错误解释 diff --git a/auto.js b/auto.js index c5054c7..735b63e 100644 --- a/auto.js +++ b/auto.js @@ -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]) @@ -24,44 +22,51 @@ 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(); - }, 300); - }, - makeFolder: function (callback) { - setTimeout(function(){ - console.log('1.1: made folder'); - callback(); - }, 200); - }, - writeFile: ['getData', 'makeFolder', function(callback) { - setTimeout(function(){ - console.log('1.1: wrote file'); - callback(null, 'myfile'); - }, 300); - }], - emailFiles: ['writeFile', function(callback, results) { - log('1.1: emailed file: ', results.writeFile); // -> myfile - 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' } -}); +//// 1.1 +//async.auto({ +// getData: function (callback) { +// setTimeout(function(){ +// console.log('1.1: got data'); +// callback(null, 'mydata'); +// }, 300); +// }, +// makeFolder: function (callback) { +// setTimeout(function(){ +// console.log('1.1: made folder'); +// callback(null, 'myfolder'); +// }, 200); +// }, +// writeFile: ['getData', 'makeFolder', function(callback) { +// setTimeout(function(){ +// console.log('1.1: wrote file'); +// callback(null, 'myfile'); +// }, 300); +// }], +// emailFiles: ['writeFile', function(callback, results) { +// log('1.1: emailed file: ', results.writeFile); +// callback(null, results.writeFile); +// }] +//}, function(err, results) { +// 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) { @@ -87,6 +92,13 @@ async.auto({ callback('err sending email', results.writeFile); }] }, function(err, results) { - log('1.2 err: ', err); // -> myerr - log('1.2 results: ', results); // -> '' -}); \ No newline at end of file + 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 } diff --git a/iterator.js b/iterator.js index 53084fd..ae43a5d 100644 --- a/iterator.js +++ b/iterator.js @@ -10,15 +10,9 @@ var log = t.log; // async.iterator(tasks) var iter = async.iterator([ - function () { - log('I am 111') - }, - function () { - log('I am 222') - }, - function () { - log('I am 333') - } + function () {log('I am 111')}, + function () {log('I am 222')}, + function () {log('I am 333')} ]); /** From 9863380e59f45af71b99b30d3706636bef4a9e9b Mon Sep 17 00:00:00 2001 From: bsspirit Date: Thu, 12 Sep 2013 16:50:21 +0800 Subject: [PATCH 23/36] 'queue' --- README.md | 1 + queue.js | 120 ++++++++++++++++++++++++++++++++++++++---------------- 2 files changed, 87 insertions(+), 34 deletions(-) diff --git a/README.md b/README.md index 26ca5d1..e9ba0b9 100644 --- a/README.md +++ b/README.md @@ -41,5 +41,6 @@ https://github.com/caolan/async 22. 增加times.js文件,包括times和timesSeries函数 23. 修改iterator.js实例 24. 修正auto.js关于第二个实例的错误解释 +25. 修改queue.js实例和注释 diff --git a/queue.js b/queue.js index b3ea7e4..f7f4c00 100644 --- a/queue.js +++ b/queue.js @@ -3,62 +3,114 @@ var t = require('./t'); var log = t.log; /** - * queue相当于一个加强版的parallel,主要是限制了worker数量,不再一次性全部执行。当worker数量不够用时,新加入的任务将会排队等候,直到有新的worker可用。 + * queue是一个串行的消息队列,主要是限制了worker数量,不再一次性全部执行。 + * 当worker数量不够用时,新加入的任务将会排队等候,直到有新的worker可用。 * * 该函数有多个点可供回调,如worker用完时、无等候任务时、全部执行完时等。 */ // queue(worker, concurrency) -// 定义一个queue,设worker数量为2 +/** + * 定义一个queue,设worker数量为2 + */ var q = async.queue(function(task, callback) { log('worker is processing task: ', task.name); task.run(callback); }, 2); -// 如果某次push操作后,任务数将达到或超过worker数量时,将调用该函数 +/** + * 监听:如果某次push操作后,任务数将达到或超过worker数量时,将调用该函数 + */ q.saturated = function() { log('all workers to be used'); } -// 当最后一个任务交给worker时,将调用该函数 +/** + * 监听:当最后一个任务交给worker时,将调用该函数 + */ q.empty = function() { log('no more tasks wating'); } -// 当所有任务都执行完以后,将调用该函数 +/** + * 监听:当所有任务都执行完以后,将调用该函数 + */ q.drain = function() { - console.log('all tasks have been processed'); + log('all tasks have been processed'); } -// 放入单个任务 -q.push({name:'t1', run: function(cb){ - log('t1 is running, waiting tasks: ', q.length()); - t.fire('t1', cb, 400); // 400ms后执行 -}}, function(err) { - log('t1 executed'); -}); - -log('pushed t1, waiting tasks: ', q.length()); +///** +// * 独立加入2个任务 +// */ +//q.push({name:'t1', run: function(cb){ +// log('t1 is running, waiting tasks: ', q.length()); +// t.fire('t1', cb, 400); // 400ms后执行 +//}}, function(err) { +// log('t1 executed'); +//}); +//log('pushed t1, waiting tasks: ', q.length()); +// +//q.push({name:'t2',run: function(cb){ +// log('t2 is running, waiting tasks: ', q.length()); +// t.fire('t2', cb, 200); // 200ms后执行 +//}}, function(err) { +// log('t2 executed'); +//}); +//log('pushed t2, waiting tasks: ', q.length()); +////54.448> pushed t1, waiting tasks: 1 +////54.451> all workers to be used +////54.452> pushed t2, waiting tasks: 2 +////54.452> worker is processing task: t1 +////54.453> t1 is running, waiting tasks: 1 +////54.455> no more tasks wating +////54.455> worker is processing task: t2 +////54.455> t2 is running, waiting tasks: 0 +////54.656> t2 executed +////54.867> t1 executed +////54.868> all tasks have been processed -q.push({name:'t2',run: function(cb){ - log('t2 is running, waiting tasks: ', q.length()); - t.fire('t2', cb, 200); // 200ms后执行 -}}, function(err) { - log('t2 executed'); -}); - -log('pushed t2, waiting tasks: ', q.length()); -// 放入多个任务 -q.push([{name:'t3', run: function(cb){ - log('t3 is running, waiting tasks: ', q.length()); - t.fire('t3', cb, 300); // 300ms后执行 -}},{name:'t4', run: function(cb){ - log('t4 is running, waiting tasks: ', q.length()); - t.fire('t4', cb, 500); // 500ms后执行 -}}], function(err) { - log('t3/4 executed'); +// 同时加入多个任务 +q.push([ + { + name:'t3', run: function(cb){ + log('t3 is running, waiting tasks: ', q.length()); + t.fire('t3', cb, 300); // 300ms后执行 + } + },{ + name:'t4', run: function(cb){ + log('t4 is running, waiting tasks: ', q.length()); + t.fire('t4', cb, 500); // 500ms后执行 + } + },{ + name:'t5', run: function(cb){ + log('t5 is running, waiting tasks: ', q.length()); + t.fire('t5', cb, 100); // 100ms后执行 + } + },{ + name:'t6', run: function(cb){ + log('t6 is running, waiting tasks: ', q.length()); + t.fire('t6', cb, 400); // 400ms后执行 + } + } +], function(err) { + log('err: ',err); }); - -log('pushed t3/t4, waiting tasks: ', q.length()); +log('pushed t3,t4,t5,t6 into queue, waiting tasks: ', q.length()); +//53.755> all workers to be used +//53.758> pushed t3,t4,t5,t6 into queue, waiting tasks: 4 +//53.759> worker is processing task: t3 +//53.760> t3 is running, waiting tasks: 3 +//53.762> worker is processing task: t4 +//53.762> t4 is running, waiting tasks: 2 +//54.073> err: null +//54.074> worker is processing task: t5 +//54.076> t5 is running, waiting tasks: 1 +//54.183> err: null +//54.184> no more tasks wating +//54.185> worker is processing task: t6 +//54.186> t6 is running, waiting tasks: 0 +//54.265> err: null +//54.588> err: null +//54.589> all tasks have been processed From 681ddc13b92e1b06dcf3927ed2b5a1a5c5c5a66b Mon Sep 17 00:00:00 2001 From: bsspirit Date: Thu, 12 Sep 2013 17:04:18 +0800 Subject: [PATCH 24/36] 'cargo' --- README.md | 1 + cargo.js | 83 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ queue.js | 2 +- 3 files changed, 85 insertions(+), 1 deletion(-) create mode 100644 cargo.js diff --git a/README.md b/README.md index e9ba0b9..af1f515 100644 --- a/README.md +++ b/README.md @@ -42,5 +42,6 @@ https://github.com/caolan/async 23. 修改iterator.js实例 24. 修正auto.js关于第二个实例的错误解释 25. 修改queue.js实例和注释 +26. 修改cargo.js文件 diff --git a/cargo.js b/cargo.js new file mode 100644 index 0000000..9efec92 --- /dev/null +++ b/cargo.js @@ -0,0 +1,83 @@ +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 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 \ No newline at end of file diff --git a/queue.js b/queue.js index f7f4c00..375f666 100644 --- a/queue.js +++ b/queue.js @@ -3,7 +3,7 @@ var t = require('./t'); var log = t.log; /** - * queue是一个串行的消息队列,主要是限制了worker数量,不再一次性全部执行。 + * queue是一个串行的消息队列,通过限制了worker数量,不再一次性全部执行。 * 当worker数量不够用时,新加入的任务将会排队等候,直到有新的worker可用。 * * 该函数有多个点可供回调,如worker用完时、无等候任务时、全部执行完时等。 From 2bab3d986d5b24ce99e7da5017a21feb80100021 Mon Sep 17 00:00:00 2001 From: bsspirit Date: Fri, 13 Sep 2013 10:31:38 +0800 Subject: [PATCH 25/36] 'applyEach' --- README.md | 1 + apply.js | 1 + applyEach.js | 79 ++++++++++++++++++++++++++++++++++++++++++++++++++++ cargo.js | 3 ++ 4 files changed, 84 insertions(+) create mode 100644 applyEach.js diff --git a/README.md b/README.md index af1f515..cac1ad1 100644 --- a/README.md +++ b/README.md @@ -43,5 +43,6 @@ https://github.com/caolan/async 24. 修正auto.js关于第二个实例的错误解释 25. 修改queue.js实例和注释 26. 修改cargo.js文件 +27. 增加applyEach.js文件 diff --git a/apply.js b/apply.js index 6800f4c..cca5650 100644 --- a/apply.js +++ b/apply.js @@ -32,6 +32,7 @@ async.parallel([ //1.2 function inc(a,b,callback,timeout){ var timeout = timeout || 200; + t.wait(200); setTimeout(function() { callback(null, a+b); }, timeout); diff --git a/applyEach.js b/applyEach.js new file mode 100644 index 0000000..1b0455d --- /dev/null +++ b/applyEach.js @@ -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 + + diff --git a/cargo.js b/cargo.js index 9efec92..b0ccf1a 100644 --- a/cargo.js +++ b/cargo.js @@ -42,6 +42,9 @@ cargo.drain = function() { log('all tasks have been processed'); } +/** + * 增加新任务 + */ cargo.push({name: 'A'}, function (err) { t.wait(300); log('finished processing A'); From e07c78dbc1e220ad8d0e046a93ca72c14122d2a0 Mon Sep 17 00:00:00 2001 From: bsspirit Date: Fri, 13 Sep 2013 11:12:06 +0800 Subject: [PATCH 26/36] 'utils.js' --- README.md | 1 + utils.js | 145 ++++++++++++++++++++++++++++++++---------------------- 2 files changed, 86 insertions(+), 60 deletions(-) diff --git a/README.md b/README.md index cac1ad1..f360e62 100644 --- a/README.md +++ b/README.md @@ -44,5 +44,6 @@ https://github.com/caolan/async 25. 修改queue.js实例和注释 26. 修改cargo.js文件 27. 增加applyEach.js文件 +28. 修改utils.js实例和注释 diff --git a/utils.js b/utils.js index 04e40f7..b1d974c 100644 --- a/utils.js +++ b/utils.js @@ -1,97 +1,122 @@ var async = require('async'); var t = require('./t'); +var log = t.log; /** - * 让某一个函数在内存中缓存它的计算结果。对于相同的参数,只计算一次,下次就直接拿到之前算好的结果。 - */ +* 让某一个函数在内存中缓存它的计算结果。对于相同的参数,只计算一次,下次就直接拿到之前算好的结果。 +* hasher可以让我们自定义如何根据参数来判断它是否已经在缓存中了。 +*/ // memoize(fn, [hasher]) - +//1.1 var slow_fn = function(x, y, callback) { - console.log('start working for: ' + x+','+y); - t.wait(100); - console.log('finished: ' + x+','+y); - callback(null, 'im slow for: '+x+','+y); + log('1.1 start working for: ' + x+','+y); + t.wait(500); + log('1.1 finished: ' + x+','+y); + callback(null, x+','+y); }; - -var fn = async.memoize(slow_fn); - +var fn = async.memoize(slow_fn,function(x,y) { + return x+y; +}); fn('a','b', function(err, result) { - console.log(result); + log("1.1 first time: "+result); +}); +fn('cc','d', function(err, result) { + log("1.1 first time: "+result); }); - -// 直接得到之前计算好的值 fn('a','b', function(err, result) { - console.log(result); + log("1.1 second time: "+result); }); +//15.416> 1.1 start working for: a,b +//15.920> 1.1 finished: a,b +//15.920> 1.1 first time: a,b +//15.921> 1.1 start working for: cc,d +//16.423> 1.1 finished: cc,d +//16.423> 1.1 first time: cc,d +//16.424> 1.1 second time: a,b + /** - * hasher可以让我们自定义如何根据参数来判断它是否已经在缓存中了。 - */ -var fn_hasher = async.memoize(slow_fn, function(x,y) { +* 让已经被缓存的函数,返回不缓存的函数引用。 +*/ +// unmemoize(fn) +//1.2 +var slow_fn2 = function(x, y, callback) { + log('1.2 start working for: ' + x+','+y); + t.wait(500); + log('1.2 finished: ' + x+','+y); + callback(null, x+','+y); +}; +var fn2 = async.memoize(slow_fn2,function(x,y) { return x+y; }); -fn_hasher('cd','e', function(err, result) { - console.log(result); -}); - -fn_hasher('c','de', function(err, result) { - console.log(result); // 可以取得前面('cd','e')的计算结果 - // im show for: cd,e +fn2('a','b', function(err,result) { + log("1.2 first time: "+result); }); +var unFn2 =async.unmemoize(fn2); +log('1.2 unmemoized'); -/** - * 让一个已经被memoize的函数不再缓存结果。 - */ -// unmemoize(fn) - -var fn2 = async.unmemoize(fn); -console.log('unmemoized'); - -fn2('a','b', function(err,result) { - console.log(result); +unFn2('a','b', function(err,result) { + log("1.2 second time: "+result); }); +//16.424> 1.2 start working for: a,b +//16.926> 1.2 finished: a,b +//16.926> 1.2 first time: a,b +//16.927> 1.2 unmemoized +//16.927> 1.2 start working for: a,b +//17.428> 1.2 finished: a,b +//17.428> 1.2 second time: a,b /** - * 执行某异步函数,并记录它的返回值。试验函数时很方便,不用写那些固定模式的代码。 - * - * 如果该函数向回调中传入了多个参数,则每行记录一个。 - */ +* 执行某异步函数,并记录它的返回值。试验函数时很方便,不用写那些固定模式的代码。 +* 如果该函数向回调中传入了多个参数,则每行记录一个。 +*/ // log(function, arguments) - +//1.3 var x = function() { - this.name = 'Freewind'; + this.name = 'bsspirit'; } var hello = function(name, callback) { setTimeout(function() { - callback(null, 'hello ' + name, 'nice to see you ' + name, x, {a:'123'}); + callback(null, + 'first ' + name, + 'second '+ name, + x, + {a:'123'} + ); }, 200); }; +log("1.3 handler"); +async.log(hello, 'time'); +//37.620> 1.3 handler +//first time +//second time +//[Function] +//{ a: '123' } -async.log(hello, 'world'); -// it prints: -// hello world -// nice to see you world -// [Function] -// { a: '123' } - -// 我不太明白dir与log之间,到底有什么大的差别。 -// http://stackoverflow.com/questions/10636866/whats-the-difference-between-async-log-and-async-dir +/** +* dir与log都是打印出输,在nodejs环境中没有分别。 +* dir的不同之处在于,会调用浏览器的console.dir()函数,显示为DOM视图。 +* +* http://stackoverflow.com/questions/10636866/whats-the-difference-between-async-log-and-async-dir +*/ +//1.4 +log("1.4 handler"); async.dir(hello, 'world'); -// it prints: -// 'hello world' -// 'nice to see you world' -// [Function] -// { a: '123' } +//37.620> 1.4 handler +//first time +//second time +//[Function] +//{ a: '123' } /** - * noConflict()仅仅用于浏览器端,在nodejs中没用,这里无法演示。 - * - * 它的作用是:如果之前已经在全局域中定义了async变量,当导入本async.js时,会先把之前的async变量保存起来,然后覆盖它。用完之后,调用noConflict()方法,就会归还该值。同时返回async本身供换名使用。 - */ +* noConflict()仅仅用于浏览器端,在nodejs中没用,这里无法演示。 +* +* 它的作用是:如果之前已经在全局域中定义了async变量,当导入本async.js时,会先把之前的async变量保存起来,然后覆盖它。 + * 用完之后,调用noConflict()方法,就会归还该值。同时返回async本身供换名使用。 +*/ // noConflict() - /* // global on the server, window in the browser var root = this, From 65a785df5e454f9db75a641bcdefac48c0e8aa4e Mon Sep 17 00:00:00 2001 From: bsspirit Date: Fri, 13 Sep 2013 11:14:42 +0800 Subject: [PATCH 27/36] 'mapLimit' --- map.js | 38 ++++++++++++++++++++++++++++++++------ 1 file changed, 32 insertions(+), 6 deletions(-) diff --git a/map.js b/map.js index 5573da9..3e40635 100644 --- a/map.js +++ b/map.js @@ -40,8 +40,8 @@ async.map(arr, function(item, callback) { // 54.879> 1.1 results: [ 'Jack!!!', 'Mike!!!', 'Freewind!!!', 'Test!!!' ] /** - * 如果中途出错,立刻将错误、以及已经执行完成的结果汇总给最终callback。未执行完的将会在结果数组中用占个空位。 - */ +* 如果中途出错,立刻将错误、以及已经执行完成的结果汇总给最终callback。未执行完的将会在结果数组中用占个空位。 +*/ async.map(arr, function(item, callback) { log('1.2 enter: ' + item.name); setTimeout(function() { @@ -65,8 +65,8 @@ async.map(arr, function(item, callback) { // 54.879> 1.2 handle: Freewind /** - * 顺序执行,一个完了才执行下一个。 - */ +* 顺序执行,一个完了才执行下一个。 +*/ async.mapSeries(arr, function(item, callback) { log('1.3 enter: ' + item.name); setTimeout(function() { @@ -89,8 +89,8 @@ async.mapSeries(arr, function(item, callback) { // 55.269> 1.3 results: [ 'Jack!!!', 'Mike!!!', 'Freewind!!!', 'Test!!!' ] /** - * 顺序执行过程中出错,只把错误以及执行完的传给最终callback,未执行的忽略。 - */ +* 顺序执行过程中出错,只把错误以及执行完的传给最终callback,未执行的忽略。 +*/ async.mapSeries(arr, function(item, callback) { log('1.4 enter: ' + item.name); setTimeout(function() { @@ -108,3 +108,29 @@ async.mapSeries(arr, function(item, callback) { // 47.931> 1.4 handle: Mike // 47.931> 1.4 err: myerr // 47.932> 1.4 results: [ 'Jack!!!', undefined ] + +/** + * 并行执行,同时最多2个函数并行,传给最终callback。 + */ +//1.5 +async.mapLimit(arr,2, function(item, callback) { + log('1.5 enter: ' + item.name); + setTimeout(function() { + log('1.5 handle: ' + item.name); + if(item.name==='Jack') callback('myerr'); + else callback(null, item.name+'!!!'); + }, item.delay); +}, function(err, results) { + log('1.5 err: ', err); + log('1.5 results: ', results); +}); +//57.797> 1.5 enter: Jack +//57.800> 1.5 enter: Mike +//57.900> 1.5 handle: Mike +//57.900> 1.5 enter: Freewind +//58.008> 1.5 handle: Jack +//58.009> 1.5 err: myerr +//58.009> 1.5 results: [ undefined, 'Mike!!!' ] +//58.208> 1.5 handle: Freewind +//58.208> 1.5 enter: Test +//58.273> 1.5 handle: Test From 023eadf32fe2b748841c39de3dd7d1f899f71865 Mon Sep 17 00:00:00 2001 From: bsspirit Date: Fri, 13 Sep 2013 12:03:04 +0800 Subject: [PATCH 28/36] 'detail' --- README.md | 4 +- applyEach.js | 2 +- auto.js | 74 ++++++------ map.js | 2 +- whilst_until.js | 292 ++++++++++++++++++++++++------------------------ 5 files changed, 188 insertions(+), 186 deletions(-) diff --git a/README.md b/README.md index f360e62..0748728 100644 --- a/README.md +++ b/README.md @@ -3,6 +3,8 @@ async_demo A demo for async. +http://blog.fens.me/nodejs-async/ + INSTALL =========================== @@ -10,7 +12,7 @@ INSTALL > cd nodejs-async && npm install -Change Log by bsspirit +Change Log =================================== 参考async@0.2.9版本的规范 diff --git a/applyEach.js b/applyEach.js index 1b0455d..19c4654 100644 --- a/applyEach.js +++ b/applyEach.js @@ -3,7 +3,7 @@ var t = require('./t'); var log = t.log; /** -* applyEach,可以实现给一数组中每个函数传参,通过callback返回。 +* applyEach,可以实现给一数组中每个函数传相同参数,通过callback返回。 * 如果只传第一个参数,将返回一个函数对象,我可以传参调用。 */ // applyEach(fns, args..., callback) diff --git a/auto.js b/auto.js index 735b63e..cf1b12f 100644 --- a/auto.js +++ b/auto.js @@ -24,43 +24,43 @@ var log = t.log; * 分析该任务,可以知道1与2可以并行执行,3需要等1和2完成,4要等3完成。 * 可以按以下方式来使用auto函数。 */ -//// 1.1 -//async.auto({ -// getData: function (callback) { -// setTimeout(function(){ -// console.log('1.1: got data'); -// callback(null, 'mydata'); -// }, 300); -// }, -// makeFolder: function (callback) { -// setTimeout(function(){ -// console.log('1.1: made folder'); -// callback(null, 'myfolder'); -// }, 200); -// }, -// writeFile: ['getData', 'makeFolder', function(callback) { -// setTimeout(function(){ -// console.log('1.1: wrote file'); -// callback(null, 'myfile'); -// }, 300); -// }], -// emailFiles: ['writeFile', function(callback, results) { -// log('1.1: emailed file: ', results.writeFile); -// callback(null, results.writeFile); -// }] -//}, function(err, results) { -// 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' } +// 1.1 +async.auto({ + getData: function (callback) { + setTimeout(function(){ + console.log('1.1: got data'); + callback(null, 'mydata'); + }, 300); + }, + makeFolder: function (callback) { + setTimeout(function(){ + console.log('1.1: made folder'); + callback(null, 'myfolder'); + }, 200); + }, + writeFile: ['getData', 'makeFolder', function(callback) { + setTimeout(function(){ + console.log('1.1: wrote file'); + callback(null, 'myfile'); + }, 300); + }], + emailFiles: ['writeFile', function(callback, results) { + log('1.1: emailed file: ', results.writeFile); + callback(null, results.writeFile); + }] +}, function(err, results) { + 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' } diff --git a/map.js b/map.js index 3e40635..9fb545c 100644 --- a/map.js +++ b/map.js @@ -4,7 +4,7 @@ var t = require('./t'); var log = t.log; /** - * 对集合中的每一个元素,执行某个异步操作,得到结果。所有的结果将汇总到最终的callback里。与forEach的区别是,forEach只关心操作不管最后的值,而map关心的最后产生的值。 + * 对集合中的每一个元素,执行某个异步操作,得到结果。所有的结果将汇总到最终的callback里。与each的区别是,each只关心操作不管最后的值,而map关心的最后产生的值。 * * 提供了两种方式: * 1. 并行执行。同时对集合中所有元素进行操作,结果汇总到最终callback里。如果出错,则立刻返回错误以及已经执行完的任务的结果,未执行完的占个空位 diff --git a/whilst_until.js b/whilst_until.js index e1169be..a4a5e9d 100644 --- a/whilst_until.js +++ b/whilst_until.js @@ -21,152 +21,152 @@ var log = t.log; */ // whilst(test, fn, callback) -///** -//* 正常情况,没有出错。第二个函数虽然是异步调用,但被同步执行。所以第三个函数被调用时,已经过了3秒。 -//*/ -//// 1.1 -//var count1 = 0; -//async.whilst( -// function() { return count1 < 3 }, -// function(cb) { -// log('1.1 count: ', count1); -// count1++; -// setTimeout(cb, 1000); -// }, -// function(err) { -// // 3s have passed -// log('1.1 err: ', err); -// } -//); -////10.318> 1.1 count: 0 -////11.330> 1.1 count: 1 -////12.342> 1.1 count: 2 -////13.356> 1.1 err: -// -// -///** -//* 中途出错。出错后立刻调用第三个函数。 -//*/ -//// 1.2 -//var count2 = 0; -//async.whilst( -// function() { return count2 < 3 }, -// function(cb) { -// log('1.2 count: ', count2); -// if(count2===1) { -// t.err('myerr', cb, 200); -// } else { -// count2++; -// setTimeout(cb, 1000); -// } -// }, -// function(err) { -// // 2s have passed -// log('1.2 err: ', err); -// } -//); -////12.805> 1.2 count: 0 -////13.824> 1.2 count: 1 -////14.026> 1.2 err: myerr -// -///** -//* 第二个函数即使产生值,也会被忽略。第三个函数只能得到err。 -//*/ -//// 1.3 -//var count3 = 0; -//async.whilst( -// function() {return count3 < 3 }, -// function(cb) { -// log('1.3 count: ', count3); -// t.inc(count3++, cb); -// }, -// function(err,result){ // result没有用 -// log('1.3 err: ', err); -// log('1.3 result: ', result); -// } -//); -////45.311> 1.3 count: 0 -////45.514> 1.3 count: 1 -////45.718> 1.3 count: 2 -////45.920> 1.3 err: -////45.923> 1.3 result: -// -///** -//* doWhilst交换了fn,test的参数位置,先执行一次循环,再做test判断。 和javascript中do..while语法一致。 -//*/ -//// doWhilst(fn, test, callback) -////1.4 -//var count4 = 0; -//async.doWhilst( -// function(cb) { -// log('1.4 count: ', count4); -// t.inc(count4++, cb); -// }, -// function() { log("1.4 test"); return count4 < 3 }, -// function(err,result){ // result没有用 -// log('1.4 err: ', err); -// log('1.4 result: ', result); -// } -//); -////33.643> 1.4 count: 0 -////33.848> 1.4 test -////33.850> 1.4 count: 1 -////34.054> 1.4 test -////34.057> 1.4 count: 2 -////34.269> 1.4 test -////34.270> 1.4 err: -////34.270> 1.4 result: -// -///** -//* until与whilst正好相反,当test为false时循环,与true时跳出。其它特性一致。 -//*/ -//// 1.5 -//var count5 = 0; -//async.until( -// function() { return count5>3 }, -// function(cb) { -// log('1.5 count: ', count5); -// count5++; -// setTimeout(cb, 200); -// }, -// function(err) { -// // 4s have passed -// log('1.5 err: ',err); -// } -//); -////42.498> 1.5 count: 0 -////42.701> 1.5 count: 1 -////42.905> 1.5 count: 2 -////43.107> 1.5 count: 3 -////43.313> 1.5 err: -// -///** -//* doUntil与doWhilst正好相反,当test为false时循环,与true时跳出。其它特性一致。 -//*/ -//// doUntil(fn, test, callback) -//// 1.6 -//var count6 = 0; -//async.doUntil( -// function(cb) { -// log('1.6 count: ', count6); -// count6++; -// setTimeout(cb, 200); -// }, -// function() { log('1.6 test');return count6>3 }, -// function(err) { -// // 4s have passed -// log('1.6 err: ',err); -// } -//); -////41.831> 1.6 count: 0 -////42.035> 1.6 test -////42.037> 1.6 count: 1 -////42.241> 1.6 test -////42.244> 1.6 count: 2 -////42.456> 1.6 test -////42.457> 1.6 count: 3 -////42.660> 1.6 test -////42.661> 1.6 err: +/** +* 正常情况,没有出错。第二个函数虽然是异步调用,但被同步执行。所以第三个函数被调用时,已经过了3秒。 +*/ +// 1.1 +var count1 = 0; +async.whilst( + function() { return count1 < 3 }, + function(cb) { + log('1.1 count: ', count1); + count1++; + setTimeout(cb, 1000); + }, + function(err) { + // 3s have passed + log('1.1 err: ', err); + } +); +//10.318> 1.1 count: 0 +//11.330> 1.1 count: 1 +//12.342> 1.1 count: 2 +//13.356> 1.1 err: + + +/** +* 中途出错。出错后立刻调用第三个函数。 +*/ +// 1.2 +var count2 = 0; +async.whilst( + function() { return count2 < 3 }, + function(cb) { + log('1.2 count: ', count2); + if(count2===1) { + t.err('myerr', cb, 200); + } else { + count2++; + setTimeout(cb, 1000); + } + }, + function(err) { + // 2s have passed + log('1.2 err: ', err); + } +); +//12.805> 1.2 count: 0 +//13.824> 1.2 count: 1 +//14.026> 1.2 err: myerr + +/** +* 第二个函数即使产生值,也会被忽略。第三个函数只能得到err。 +*/ +// 1.3 +var count3 = 0; +async.whilst( + function() {return count3 < 3 }, + function(cb) { + log('1.3 count: ', count3); + t.inc(count3++, cb); + }, + function(err,result){ // result没有用 + log('1.3 err: ', err); + log('1.3 result: ', result); + } +); +//45.311> 1.3 count: 0 +//45.514> 1.3 count: 1 +//45.718> 1.3 count: 2 +//45.920> 1.3 err: +//45.923> 1.3 result: + +/** +* doWhilst交换了fn,test的参数位置,先执行一次循环,再做test判断。 和javascript中do..while语法一致。 +*/ +// doWhilst(fn, test, callback) +//1.4 +var count4 = 0; +async.doWhilst( + function(cb) { + log('1.4 count: ', count4); + t.inc(count4++, cb); + }, + function() { log("1.4 test"); return count4 < 3 }, + function(err,result){ // result没有用 + log('1.4 err: ', err); + log('1.4 result: ', result); + } +); +//33.643> 1.4 count: 0 +//33.848> 1.4 test +//33.850> 1.4 count: 1 +//34.054> 1.4 test +//34.057> 1.4 count: 2 +//34.269> 1.4 test +//34.270> 1.4 err: +//34.270> 1.4 result: + +/** +* until与whilst正好相反,当test为false时循环,与true时跳出。其它特性一致。 +*/ +// 1.5 +var count5 = 0; +async.until( + function() { return count5>3 }, + function(cb) { + log('1.5 count: ', count5); + count5++; + setTimeout(cb, 200); + }, + function(err) { + // 4s have passed + log('1.5 err: ',err); + } +); +//42.498> 1.5 count: 0 +//42.701> 1.5 count: 1 +//42.905> 1.5 count: 2 +//43.107> 1.5 count: 3 +//43.313> 1.5 err: + +/** +* doUntil与doWhilst正好相反,当test为false时循环,与true时跳出。其它特性一致。 +*/ +// doUntil(fn, test, callback) +// 1.6 +var count6 = 0; +async.doUntil( + function(cb) { + log('1.6 count: ', count6); + count6++; + setTimeout(cb, 200); + }, + function() { log('1.6 test');return count6>3 }, + function(err) { + // 4s have passed + log('1.6 err: ',err); + } +); +//41.831> 1.6 count: 0 +//42.035> 1.6 test +//42.037> 1.6 count: 1 +//42.241> 1.6 test +//42.244> 1.6 count: 2 +//42.456> 1.6 test +//42.457> 1.6 count: 3 +//42.660> 1.6 test +//42.661> 1.6 err: /** * forever,无论条件循环执行,如果不出错,callback永远不被执行 From 1f5b0a1583ceb9aba943d80da862445239860a56 Mon Sep 17 00:00:00 2001 From: bsspirit Date: Fri, 13 Sep 2013 12:07:14 +0800 Subject: [PATCH 29/36] 'update' --- queue.js | 58 ++++++++++++++++++++++++++++---------------------------- 1 file changed, 29 insertions(+), 29 deletions(-) diff --git a/queue.js b/queue.js index 375f666..ea078a0 100644 --- a/queue.js +++ b/queue.js @@ -39,35 +39,35 @@ q.drain = function() { log('all tasks have been processed'); } -///** -// * 独立加入2个任务 -// */ -//q.push({name:'t1', run: function(cb){ -// log('t1 is running, waiting tasks: ', q.length()); -// t.fire('t1', cb, 400); // 400ms后执行 -//}}, function(err) { -// log('t1 executed'); -//}); -//log('pushed t1, waiting tasks: ', q.length()); -// -//q.push({name:'t2',run: function(cb){ -// log('t2 is running, waiting tasks: ', q.length()); -// t.fire('t2', cb, 200); // 200ms后执行 -//}}, function(err) { -// log('t2 executed'); -//}); -//log('pushed t2, waiting tasks: ', q.length()); -////54.448> pushed t1, waiting tasks: 1 -////54.451> all workers to be used -////54.452> pushed t2, waiting tasks: 2 -////54.452> worker is processing task: t1 -////54.453> t1 is running, waiting tasks: 1 -////54.455> no more tasks wating -////54.455> worker is processing task: t2 -////54.455> t2 is running, waiting tasks: 0 -////54.656> t2 executed -////54.867> t1 executed -////54.868> all tasks have been processed +/** +* 独立加入2个任务 +*/ +q.push({name:'t1', run: function(cb){ + log('t1 is running, waiting tasks: ', q.length()); + t.fire('t1', cb, 400); // 400ms后执行 +}}, function(err) { + log('t1 executed'); +}); +log('pushed t1, waiting tasks: ', q.length()); + +q.push({name:'t2',run: function(cb){ + log('t2 is running, waiting tasks: ', q.length()); + t.fire('t2', cb, 200); // 200ms后执行 +}}, function(err) { + log('t2 executed'); +}); +log('pushed t2, waiting tasks: ', q.length()); +//54.448> pushed t1, waiting tasks: 1 +//54.451> all workers to be used +//54.452> pushed t2, waiting tasks: 2 +//54.452> worker is processing task: t1 +//54.453> t1 is running, waiting tasks: 1 +//54.455> no more tasks wating +//54.455> worker is processing task: t2 +//54.455> t2 is running, waiting tasks: 0 +//54.656> t2 executed +//54.867> t1 executed +//54.868> all tasks have been processed // 同时加入多个任务 From 851aa8477066bc8a073465cc9db173a2d8d15ea2 Mon Sep 17 00:00:00 2001 From: Conan Zhang Date: Thu, 14 Aug 2014 14:16:22 +0800 Subject: [PATCH 30/36] Update README.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit readme增加注释 --- README.md | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 0748728..b7f310a 100644 --- a/README.md +++ b/README.md @@ -3,14 +3,16 @@ async_demo A demo for async. -http://blog.fens.me/nodejs-async/ ++ http://blog.fens.me/nodejs-async/ ++ http://blog.fens.me/nodejs-async-timer/ INSTALL =========================== -> git clone https://github.com/caolan/async.git nodejs-async - -> cd nodejs-async && npm install +```{bash} +git clone https://github.com/caolan/async.git nodejs-async +cd nodejs-async && npm install +``` Change Log =================================== From c4bea111f62a69a08c03d9306574687ae27c952d Mon Sep 17 00:00:00 2001 From: Conan Zhang Date: Thu, 14 Aug 2014 14:19:54 +0800 Subject: [PATCH 31/36] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index b7f310a..4b5705d 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ INSTALL =========================== ```{bash} -git clone https://github.com/caolan/async.git nodejs-async +git clone https://github.com/bsspirit/async_demo.git cd nodejs-async && npm install ``` From 12eaf54c14d2210c31ad356c096e85aa42ad8a98 Mon Sep 17 00:00:00 2001 From: Conan Zhang Date: Thu, 14 Aug 2014 14:20:38 +0800 Subject: [PATCH 32/36] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 4b5705d..4f3c74d 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ INSTALL ```{bash} git clone https://github.com/bsspirit/async_demo.git -cd nodejs-async && npm install +cd async_demo ``` Change Log From 8d8acff0285bbd58749ed676b9ae19b826d1ba72 Mon Sep 17 00:00:00 2001 From: gejiawen <806717031@qq.com> Date: Mon, 2 Nov 2015 15:28:23 +0800 Subject: [PATCH 33/36] fix typo --- queue.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/queue.js b/queue.js index ea078a0..6ee63d1 100644 --- a/queue.js +++ b/queue.js @@ -29,7 +29,7 @@ q.saturated = function() { * 监听:当最后一个任务交给worker时,将调用该函数 */ q.empty = function() { - log('no more tasks wating'); + log('no more tasks waiting'); } /** From 49bbe2eac141ef4b20d124ae798080cb03733b3e Mon Sep 17 00:00:00 2001 From: ifivebig Date: Fri, 5 Aug 2016 11:55:37 +0800 Subject: [PATCH 34/36] fix a misleading typo in some.js MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It should be “并行” in first example --- some.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/some.js b/some.js index b74f53f..a9a16ed 100644 --- a/some.js +++ b/some.js @@ -12,7 +12,7 @@ var log = t.log; var arr = [1,2,3,6]; /** - * 串行执行,集合中至少有一个元素<=3,所以结果为true + * 并行执行,集合中至少有一个元素<=3,所以结果为true */ // 1.1 async.some(arr, function(item,callback){ From 0d30c3e540bccc641a7de0858a407f8655b06ff2 Mon Sep 17 00:00:00 2001 From: ifivebig Date: Fri, 5 Aug 2016 12:00:22 +0800 Subject: [PATCH 35/36] fix a misleading typo in every.js plz see the changelist --- every.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/every.js b/every.js index dcceb8e..c537af4 100644 --- a/every.js +++ b/every.js @@ -12,7 +12,7 @@ var log = t.log; var arr = [1,2,3,6]; /** - * 串行执行,集合中所有的元素都<=10,所以为true + * 并行执行,集合中所有的元素都<=10,所以为true */ async.every(arr, function(item,callback){ log('1.1 enter: ',item); @@ -34,7 +34,7 @@ async.every(arr, function(item,callback){ // 32.233> 1.1 result: true /** - * 串行执行,集合中至少有一个元素不大于2,所以为false + * 并行执行,集合中至少有一个元素不大于2,所以为false */ async.every(arr, function(item,callback){ log('1.2 enter: ',item); From 0ea2a78d016386cdf6466f7eb60a3ad0da3e2160 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 19 Dec 2016 14:41:08 +0800 Subject: [PATCH 36/36] =?UTF-8?q?auto.js=E4=B8=AD=E5=8F=82=E6=95=B0?= =?UTF-8?q?=E9=94=99=E8=AF=AF=E5=AF=BC=E8=87=B4=E6=97=A0=E6=B3=95=E6=AD=A3?= =?UTF-8?q?=E5=B8=B8=E8=BF=90=E8=A1=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- auto.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/auto.js b/auto.js index cf1b12f..7a2c6d4 100644 --- a/auto.js +++ b/auto.js @@ -81,13 +81,13 @@ 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); }]