-
Notifications
You must be signed in to change notification settings - Fork 0
/
generator.js
116 lines (104 loc) · 3.22 KB
/
generator.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
'use strict'
// function* fib() {
// var v1 = 0, v2 = 1;
// console.log(yield v1);
// console.log(yield v2);
// while (true) {
// v2 = v2 + v1;
// console.log(yield v2);
// v1 = v2 - v1;
// }
// }
// var gen = fib();
// for (var i = 0; i < 10; i++) {
// console.log(gen.next('get fib ').value);
// }
// 用setTimeout模拟某些异步操作
// function task () {
// console.log('do task1');
// // do task1
// setTimeout(function (result1) {
// console.log('on task1');
// console.log('do task2');
// setTimeout(function (result2) {
// console.log('on task2');
// console.log('do task3');
// setTimeout(function (result3) {
// console.log('on task3');
// })
// }, 2000);
// }, 1000);
// };
// task();
var fs = require('fs');
var readFile = thunkify(fs.readFile);
function thunkify(fn){
// 返回wrapper函数,wrapper函数不立刻执行fn,而仅仅是保存参数
return function(){
var args = Array.prototype.slice.call(arguments);
var ctx = this;
// wrapper函数返回一个新函数,caller可以在新函数调用中设置done回调函数
return function(done){
args.push(function(){
done.apply(null, arguments);
});
try {
fn.apply(ctx, args);
} catch (err) {
done(err);
}
}
}
};
function* task (param) {
console.log('func arg:' + param);
console.log('read file1');
var ret1 = yield readFile('file1.txt');
console.log('file1:' + ret1[1]);
console.log('read file2');
var ret2 = yield readFile('file2.txt');
console.log('file2:' + ret2[1]);
console.log('read file3');
var ret3 = yield readFile('file3.txt');
console.log('file3:' + ret3[1]);
console.log('read file1~3');
var ret4 = yield [readFile('file1.txt'), readFile('file2.txt'), readFile('file3.txt')];
console.log('file1~3:' + ret4[0][1]+"|"+ret4[1][1]+"|"+ret4[2][1]);
return "ret value:" + ret1[1] + ret2[1];
}
var co_call = function (flow, get_return) {
var slice = Array.prototype.slice;
// generator的参数
var gen = flow(slice.call(arguments, 2));
var next = function (data) {
// data赋值给yield左值&从yield处执行flow知道下一个yield
// 返回yield右值& ret.value是个thunk
var ret = gen.next(data);
if( ret.done ){
get_return(ret.value);
return;
}
//返回一组thunk函数?
if (Array.isArray(ret.value)) {
var count = ret.value.length;
// 返回一个二维数组
var results = [];
ret.value.forEach(function (item, index) {
item(function () {
count--;
results[index] = slice.call(arguments);
if (count === 0) {
next(results);
}
});
});
}else {
ret.value(function () {
// 异步回调的所有返回值生成新数组,传给yield左值
next(slice.call(arguments));
});
}
}
next();
};
co_call(task, function (ret) {console.log(ret)},'first_arg', 'second_arg');