-
Notifications
You must be signed in to change notification settings - Fork 170
/
Copy pathtest.js
313 lines (258 loc) · 7.44 KB
/
test.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
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
const fs = require('fs')
const path = require('path')
const thunkify = require('thunkify')
const co = require('co')
const Q = require('q')
function fn1() {
function* Hello() {
yield 100
yield (function () {return 200})()
return 300
}
var h = Hello()
console.log(typeof h) // object
console.log(h.next()) // { value: 100, done: false }
console.log(h.next()) // { value: 200, done: false }
console.log(h.next()) // { value: 300, done: true }
console.log(h.next()) // { value: undefined, done: true }
}
// fn1()
function fn2() {
const symbolA = Symbol.a
const obj = {
'a': 100,
'b': function () {console.log('this is b')},
symbolA: function () {console.log('this is symbol')}
}
}
// fn2()
function fn3() {
// console.log(Array.prototype.slice)
// console.log(Array.prototype[Symbol.iterator])
// let item
// for (item of [100, 200, 300]) {
// console.log(item)
// }
const arr = [100, 200, 300]
const iterator = arr[Symbol.iterator]()
// console.log(iterator.next())
// console.log(iterator.next())
// console.log(iterator.next())
// console.log(iterator.next())
// let i
// for (i of iterator) {
// console.log(i)
// }
function* Hello() {
yield 100
yield (function () {return 200})()
return 300
}
const h = Hello()
console.log(h[Symbol.iterator]) // [Function: [Symbol.iterator]]
// console.log(h.next()) // { value: 100, done: false }
// console.log(h.next()) // { value: 200, done: false }
// console.log(h.next()) // { value: 300, done: false }
// console.log(h.next()) // { value: undefined, done: true }
let i
for (i of h) {
console.log(i)
}
}
// fn3()
function fn4() {
// function* G() {
// const a = yield 100
// console.log('a', a)
// const b = yield 200
// console.log('b', b)
// const c = yield 300
// console.log('c', c)
// }
// const g = G()
// g.next() // value: 100
// g.next('aaa') // value: 200
// g.next('bbb') // value: 300
// g.next('ccc') // value: undefined
// function* fibonacci() {
// let [prev, curr] = [0, 1]
// for (;;) {
// [prev, curr] = [curr, prev + curr]
// // 将中间值通过 yield 返回,并且保留函数执行的状态,因此可以非常简单的实现 fibonacci
// yield curr
// }
// }
// for (let n of fibonacci()) {
// if (n > 1000) {
// break
// }
// console.log(n)
// }
function* G1() {
yield 'a'
yield* G2()
yield 'b'
}
function* G2() {
yield 'x'
yield 'y'
}
for (let item of G1()) {
console.log(item)
}
}
// fn4()
function fn5() {
// const thunk = function (fileName, codeType) {
// // 返回一个只接受 callback 参数的函数
// return function (callback) {
// fs.readFile(fileName, codeType, callback)
// }
// }
// const fileName = path.resolve(__dirname, '../data/data1.json')
// const readFileThunk = thunk(fileName, 'utf-8')
// readFileThunk((err, data) => {
// console.log(data.toString())
// })
const thunk = thunkify(fs.readFile)
const fileName = path.resolve(__dirname, '../data/data1.json')
const readFileThunk = thunk(fileName, 'utf-8')
readFileThunk((err, data) => {
// 获取文件内容
console.log(data)
})
}
// fn5()
function fn6() {
const readFileThunk = thunkify(fs.readFile)
const fileName1 = path.resolve(__dirname, '../data/data1.json')
const fileName2 = path.resolve(__dirname, '../data/data2.json')
const gen = function* () {
const r1 = yield readFileThunk(fileName1)
console.log(111, r1.toString())
const r2 = yield readFileThunk(fileName2)
console.log(222, r2.toString())
}
const g = gen()
g.next().value((err, data1) => {
g.next(data1).value((err, data2) => {
g.next(data2)
})
})
}
// fn6()
function fn7() {
// 自动流程管理的函数
function run(generator) {
const gen = generator()
function next(err, data) {
const result = gen.next(data) // 返回 { value: [Function], done: ... }
if (result.done) {
// result.done 表示是否结束
return
}
result.value(next) // result.value 是一个 thunk 函数
// 思考:如果 yield 后面不是 thunk 函数而是 promise 对象,上一句的 result.value(next) 就可以变为 result.value.then(next)
}
next() // 手动执行以启动第一次 next
}
const readFileThunk = thunkify(fs.readFile)
const fileName1 = path.resolve(__dirname, '../data/data1.json')
const fileName2 = path.resolve(__dirname, '../data/data2.json')
const gen = function* () {
const r1 = yield readFileThunk(fileName1)
console.log(111, r1.toString())
const r2 = yield readFileThunk(fileName2)
console.log(222, r2.toString())
}
// run(gen)
const c = co(gen)
c.then(data => {
console.log('结束')
})
}
// fn7()
function fn8() {
const fileName1 = path.resolve(__dirname, '../data/data1.json')
const fileName2 = path.resolve(__dirname, '../data/data2.json')
const readFilePromise = Q.denodeify(fs.readFile)
const gen = function* () {
const r1 = yield readFilePromise(fileName1)
console.log(111, r1.toString())
const r2 = yield readFilePromise(fileName2)
console.log(222, r2.toString())
}
co(gen)
}
// fn8()
function fn9() {
let info = ''
function* g1() {
info += '1'
yield* g2()
info += '5'
}
function* g2() {
info += '2'
yield* g3()
info += '4'
}
function* g3() {
info += '3'
}
var g = g1()
g.next()
console.log(info) // 12345
}
// fn9()
function fn10() {
class MyKoa extends Object {
constructor(props) {
super(props);
// 存储所有的中间件
this.middlewares = []
}
// 注入中间件
use (generator) {
this.middlewares.push(generator)
}
// 执行中间件
listen () {
this._run()
}
_run () {
const ctx = this
const middlewares = ctx.middlewares
co(function* () {
let prev = null
let i = middlewares.length
//从最后一个中间件到第一个中间件的顺序开始遍历
while (i--) {
//实际koa的ctx应该指向server的上下文,这里做了简化
//prev 将前面一个中间件传递给当前中间件
prev = middlewares[i].call(ctx, prev);
}
//执行第一个中间件
yield prev;
})
}
}
// 实验效果
var app = new MyKoa();
app.use(function *(next){
this.body = '1';
yield next;
this.body += '5';
console.log(this.body);
});
app.use(function *(next){
this.body += '2';
yield next;
this.body += '4';
});
app.use(function *(next){
this.body += '3';
});
app.listen();
}
fn10()