

js中yield实现同步原理
source link: https://laboo.top/2019/11/25/jsyield/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

js中yield实现同步原理
Posted on
2019-11-25 Edited on 2021-12-15 In 技术分享
在js中需要将异步方法同步的时候, 经常使用的是async
和await
, 或者用Promise
偶然在dvajs中看到其使用yield
迭代器实现了同步的效果, 例如
function* f(){
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";
}
当然直接运行不能得到预期的效果, Promise
没用同步执行, yield
返回的结果也是undefined
, 因为还缺少对其的一层封装, 或者说还缺少个执行器
var it = f();
it.next();
it.next();
it.next();
传统的迭代器, 是这样使用的
function* 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
的效果
function 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
});
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK