-
Notifications
You must be signed in to change notification settings - Fork 397
/
forEach.js
145 lines (134 loc) · 4.23 KB
/
forEach.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
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