gpt4 book ai didi

Javascript 生成器 : Understanding them

转载 作者:IT老高 更新时间:2023-10-28 22:08:14 27 4
gpt4 key购买 nike

我很确定我对生成器的理解天生就被打破了。所有在线资源似乎都相互冲突,这使得学习体验非常困难和困惑。

据我了解,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);
})();

代替:

db.get("user", function(results) {
view.display(results);
});

好吧,在我尝试编写自己的生成器之前,一切都很好。我遇到了几个问题:

  • 我上面的第一个示例代码不会运行,因为没有什么可以迭代生成器,对吗?某些更高的存在必须在某处调用 .next,对吗?
  • 必须重写整个 API,直至 I/O 调用以支持生成器,对吗?
  • 据我所知,yield 似乎代表 等待值 最常见的用例,而在实现部分(阅读:返回值到/内部 db.get) yield 似乎代表将此值发送回当前等待的 block 以恢复执行

举个例子:

function *fn() {
yield 1;
yield "a";
}

var gen = fn();
gen.next(); // 1
gen.next(); // "a";

yield 在该上下文中是向下发送值而不是等待结果。在上面的第一个示例中,它等待来自 db.get 的结果并恢复执行,而不是“返回”或发回一个值。如果 db.get 情况为真,这不是天生同步的吗?我的意思是,它不完全一样:

(function() {
//Wait for the results
var results = fs.readFileSync("users.txt");
// Use results
view.display(results);
})();

不幸的是,如果从这个问题中可以清楚地看出(可能是唯一清楚的)就是我不了解生成器。希望我能在这里得到一些见解。

最佳答案

TL;DR:生成器的本质是控制代码执行的暂停。

生成器本身可以引用this .

总而言之,您应该区分三个组件:1.生成器函数2.发电机3. 生成结果

Generator 函数只是一个 function,其头部带有星号,(可选)yield 在其主体中。

function *generator() {
console.log('Start!');
var i = 0;
while (true) {
if (i < 3)
yield i++;
}
}

var gen = generator();
// nothing happens here!!

Generator 函数本身只返回一个生成器,在上面的例子中,gen。这里没有控制台输出,因为只有在返回的 generatornext 方法被调用后 generator function 的主体才会运行。Generator 有几种方法,其中最重要的一种是nextnext 运行代码并返回生成器结果

var ret = gen.next();
// Start!
console.log(ret);
// {value: 0, done: false}

ret 上面是生成器结果。它有两个属性:value,你在generator function中产生的值,和done,一个标志generator function 返回。

console.log(gen.next());
// {value: 1, done: false}
console.log(gen.next());
// {value: 2, done: false}
console.log(gen.next());
// {value: undefined, done: true}

在这一点上,没有人会期望你了解生成器,至少不了解生成器的异步功能。

简单来说,生成器有两个特点:

  • 可以选择跳出函数,让外部代码决定何时跳回函数。
  • 异步调用的控制可以在您的代码之外完成

在代码中,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
*/

看到了吗?生成器函数本身不处理回调。外部代码可以。

基地在这里。您可以详细说明此代码以支持完全异步,同时保持生成器功能类似于同步功能。

例如,假设 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);
});

如需更完整的指南,请参阅 this .以及像 co 这样的存储库, galaxy , suspend等等。

关于Javascript 生成器 : Understanding them,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20768922/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com