javascript - Javascript生成器:了解它们

  显示原文与译文双语对照的内容
0 0

我很确定我的理解生成器本身坏了。 似乎所有在线资源冲突,这都为相当的困难和困惑的学习体验。

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

对,这都是好的,直到我试图将我自己的发电机。 我碰到几个hitches :

  • 上面的示例代码中,我首先将不会运行,因为没有什么对生成器进行迭代,对吧? 要有一些更大的调用了 .next在某个地方,对?
  • 整个API都必须重新编写,来观察I/O调用以支持生成器,对吧?
  • 残暴 yield似乎代表了最通用的用例而在implementation部分( read: 等待值 返回值to/inside db.get) yield似乎开始成为当前等待块继续执行 将此值回。

又例如:

function *fn() {
    yield 1;
    yield "a";
}
var gen = fn();
gen.next(); // 1
gen.next(); // "a";

yield在这种情况下是值发送回地上而不是等待结果。 上面的第一个例子中,它会等待的返回结果 db.get然后继续执行而不是" 返回" 或发送回一个值。 如果 db.get如果为true,这本质上无法同步? 我是说,不是它完全相同:

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

不幸的是这个问题( 也可能是唯一的,如果是任何方式清除clear执行) 是我所不了解的发电机。 希望我在这里可能会得到一些关于

时间:原作者:6个回答

0 0

tl ;DR: 接口是的实质控制暂停代码执行。

为生成器本身,则可以引用该 ?

概括来说,就三个组件应区分: 1 。 generator函数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. 没有在这里控制台输出,因为只有当这个返回产生器's next方法被调用时将运行 生成器函数体中。 发电机有多种方法,其中最重要的一个原因是 next. next运行该代码并返回结果 生成器。

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

ret上面是 生成器结果。 它有两个属性: value,你 生成器函数中yield的值,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}

至此,没有人会希望你明白生成器,至少不是每个作业的次幂的生成器。

到简单的说,发动机有两个功能:

  • 可以选择以跳出一个函数并让外部代码来决定什么时候会重新进入该函数。
  • 也可以执行异步调用的控制之外的代码

在代码中, 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 set timer');
/* result:
    generated generator
    start
    0
    Execute after timer set
    1
    Execute after timer fire
*/

明白? generator函数本身不会处理回调。 벻之外。

基本都在这儿。 你可以使用这项功能类似于同步代码来支持完整的同时保持asynchronousity生成器1 。

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

要获得更全面的指南,请参考该 and repository 一样,银河系 暂停和等等。

原作者:
0 0

没有一个async东西如果部分发电机。 发电机简单地暂停和恢复的代码块。 async所有神奇都在使用我称之为" 生成器引擎" 像 https://github .com/visionmedia/co

,就是将 gen.next()作用就是返回最后一个 yielded值并允许返回值如果 yield正被分配给东西,ex 。 var something = yield 1. 所以如果你有一段代码:

function* genfun() {
  var a = yield 1
  var b = yield 2
}
var gen = genfun()
gen.next() // returns the first yielded value via `{value: 1}`
gen.next(1) // sets `a` as 1, returns the next yielded value via `{value: 2}`
gen.next(2) // sets `b` as 2, the generator is done, so it returns `{done: true}`

gen.throw(err)接下来相同,不同则抛出错误而不是对象赋给一个变量。

这就是控制流引擎用,获取下一个值,该值可能是回调什么的 执行回调并不 gen.next()在回调完成之前。

原作者:
0 0

这两个例子并不一样。 现在yield时,该函数实际将变为凌晨时执行回调以等待db .get( " 用户" ) 完成。 这样,该函数不会阻塞其他函数的执行。 把它想象成一个方法可以把异步函数转换为同步函数,从而让系统知道你可以暂停某些点处。

原作者:
...