Adr*_*ney 20 javascript yield generator node.js
我很确定我对发电机的理解本质上已被打破.所有在线资源似乎都存在冲突,这会带来令人难以置信的困难和令人困惑的学习体验.
据我所知,该yield关键字使当前正在执行的代码块等待一个值,而不是抛出要在回调中执行的剩余代码.因此,正如大多数教程所指出的那样,您可以使用:
(function *() {
// Wait until users have be got and put into value of `results`
var results = yield db.get("users");
// And continue
view.display(results);
})();
Run Code Online (Sandbox Code Playgroud)
代替:
db.get("user", function(results) {
view.display(results);
});
Run Code Online (Sandbox Code Playgroud)
是的,在我尝试编写自己的发电机之前,这一切都很好.我遇到了几个问题:
.next某个地方,对吗?yield似乎代表值等待最常见的用例,而在实现部分(读取:返回值为/ inside db.get)yield似乎代表将此值发送回当前正在等待的块以恢复执行.举个例子:
function *fn() {
yield 1;
yield "a";
}
var gen = fn();
gen.next(); // 1
gen.next(); // "a";
Run Code Online (Sandbox Code Playgroud)
yield在该上下文中,将值返回而不是等待结果.在上面的第一个示例中,它等待来自db.get和恢复执行的结果,而不是"返回"或发回一个值.如果db.get情况属实,这本身并不是同步的吗?我的意思是,它不完全相同:
(function() {
//Wait for the results
var results = fs.readFileSync("users.txt");
// Use results
view.display(results);
})();
Run Code Online (Sandbox Code Playgroud)
不幸的是,如果从这个问题中明确表示(可能唯一清楚的是)我不了解发电机.希望我能在这里获得一些见解.
Her*_*lme 21
TL; DR:生成器的本质是控制代码执行的暂停.
对于发电机本身,您可以参考这个.
总而言之,您应该区分三个组件:1.生成器功能2.生成器3.生成结果
发电机功能简单就是function头部的星形和(可选)yield的身体.
function *generator() {
console.log('Start!');
var i = 0;
while (true) {
if (i < 3)
yield i++;
}
}
var gen = generator();
// nothing happens here!!
Run Code Online (Sandbox Code Playgroud)
在上面的情况下,发电机功能本身不做任何事情,只返回发电机gen.这里因为只返回后无控制台输出生成的next方法被调用的身体产生功能将运行.Generator有几种方法,其中最重要的是next.next运行代码并返回生成器结果.
var ret = gen.next();
// Start!
console.log(ret);
// {value: 0, done: false}
Run Code Online (Sandbox Code Playgroud)
ret以上是发电机结果.它有两个属性:value,你在生成器函数中产生的值,以及done一个指示生成器函数是否返回的标志.
console.log(gen.next());
// {value: 1, done: false}
console.log(gen.next());
// {value: 2, done: false}
console.log(gen.next());
// {value: undefined, done: true}
Run Code Online (Sandbox Code Playgroud)
在这一点上,没有人会期望你理解发电机,至少不是发电机的异步功率.
简而言之,发电机有两个特点:
在代码中,yield跳转到函数外部,然后next(val)跳回函数并将值传递回函数.外部代码可以处理异步调用并决定切换到您自己的代码的适当时间.
再看一下样本:
var gen = generator();
console.log('generated generator');
console.log(gen.next().value);
// mock long long processing
setTimeout(function() {
console.log(gen.next().value);
console.log('Execute after timer fire');
}, 1000);
console.log('Execute after timer set');
/* result:
generated generator
start
0
Execute after timer set
1
Execute after timer fire
*/
Run Code Online (Sandbox Code Playgroud)
看到?生成器函数本身不处理回调.外部代码可以.
基地就在这里.您可以详细说明此代码以支持完全异步,同时保持生成器功能,如同步.
例如,假设geturl是一个返回promise对象的异步调用.你可以写var html = yield getUrl('www.stackoverflow.com');这个跳出你的代码.外部代码将执行以下操作:
var ret = gen.next();
ret.then(function (fetchedHTML) {
// jumps back to your generator function
// and assign fetchHTML to html in your code
gen.next(fetchedHTML);
});
Run Code Online (Sandbox Code Playgroud)
有关更完整的指南,请参阅此内容.和co,galaxy,suspend等存储库一样
| 归档时间: |
|
| 查看次数: |
4734 次 |
| 最近记录: |