在js中需要将异步方法同步的时候, 经常使用的是async
和await
, 或者用Promise
偶然在dvajs中看到其使用yield
迭代器实现了同步的效果, 例如
1 | function* f(){ |
当然直接运行不能得到预期的效果, Promise
没用同步执行, yield
返回的结果也是undefined
, 因为还缺少对其的一层封装, 或者说还缺少个执行器1
2
3
4var it = f();
it.next();
it.next();
it.next();
传统的迭代器, 是这样使用的1
2
3
4
5
6
7
8
9function* range(){
for(let i=0;i<n;i++){
yield i;
}
}
var it = range();
console.log(it.next().value); // 0
console.log(it.next().value); // 1
console.log(it.next().value); // 2
如下封装, 在每一次yield
返回的Promise
的then
中进行下一次迭代, 并把结果传入g.next(r)
, 迭代函数的next(r)
中的参数r
会成为函数体中yield
标识的表达式的返回值, 从而达到类似await
的效果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
28function async(g) {
var ctx = this;
return new Promise(function(resolve, reject) {
g = g.apply(ctx);
next();
function next(r) {
var result = g.next(r);
if (result.done){
return resolve(result.value);
}
result.value.then(next);
}
});
}
async(function*(){
var a = Promise.resolve(1);
console.log(a); // Promise
var ra = yield a;
console.log(ra); // 1
var b = Promise.resolve(2);
console.log(b); // Promise
var rb = yield b;
console.log(rb); // 2
return "success";
}).then(v=>{
console.log(v) // success
});