【问题标题】:Can we pass parameters to a generator when we iterate it via for..of?当我们通过 for..of 迭代生成器时,我们可以将参数传递给生成器吗?
【发布时间】:2019-01-13 01:58:13
【问题描述】:

我正在考虑建立一个承诺队列的场景:

//Let's assume that promises is an array of promises
var promiseQueue = [];
for (var promise of promises) {
    if (promiseQueue.length) promiseQueue[promiseQueue.length - 1].then(promise);
    promiseQueue.push(promise);
}

我正在考虑实现一个名为 resolverfunction

function *resolve() {
    var promise;
    while (promise = yield) Promise.resolve(promise);
}

然后迭代它:

var promiseGenerator = resolve();

问题是这里的 for..of 将负责实际的迭代:

for (var r of promiseGenerator) {

}

在上面的代码中生成器将被成功迭代,但不幸的是我不知道在for..of的迭代中成功将参数传递给这个生成器的方法。

我想澄清一下,我不需要替代方案,我完全清楚我们可以做这样的事情:

for (var p in promiseQueue) promiseGenerator.next(promiseQueue[p]);

我特别想知道在执行 for..of 循环时是否可以将参数传递给生成器。

编辑

amn 提出的问题是,在他/她关注的示例中,总是会得到undefined。如果我们将undefined 传递给next(),这是真的,但如果我们传递其他东西,则不是真的。我提出的问题是 for..of 循环不允许我们将任何内容传递给yield,这就是这个特定问题的全部内容,该示例仅是对问题的说明,表明我们将create 永远不会在 for..of 循环中创建。然而,在 for..of 循环范围之外,Iterable 对象也有生命,我们可以将定义的值传递给yield。带有批评代码块的示例如下所示:

function *resolve() {
    var promise;
    while (promise = yield) Promise.resolve(promise);
}

var responses = [];
var f = resolve();
var temp;
for (var i = 10; !(temp = f.next(i)).done; i--) responses.push(temp);

正如我们在上面看到的,上面的yield 不能被假定为undefined。当然我们可以传递一些自定义的thenables,比如

Promise.resolve({ 
  then: function(onFulfill, onReject) { onFulfill('fulfilled!'); }
});

甚至是尚未解决的承诺。该示例的重点是表明我们不能使用 for..of 循环将值传递给yield,在我看来这是一个很大的功能差距。

【问题讨论】:

  • for..of 循环的全部意义在于自动为您调用迭代器上的.next(),因此无法将值传入。也许将问题集中起来会更好为什么要这样做,以便人们可以提供替代建议?
  • @loganfsmyth 我的目标是理解语法。到目前为止,for..of 似乎是不可能的,但我想知道事实是否如此。
  • 真的不清楚你想用承诺做什么。我建议看看async/await
  • @Bergi 我必须在周五做一个关于 ES6 的演讲,所以我的目标是理解语法。除了这个问题,我已经弄清楚了我对自己提出的大部分问题。
  • while (promise = yield) Promise.resolve(promise); 声明对我来说毫无意义。首先,您将undefinedyield 表达式的值)分配给一个变量,这显然会取消一开始从未运行过的循环,但只有在实际产生undefined 之后,这甚至没有谈论什么如果循环已经运行,就会发生 - 再次使用 undefined 创建一个使用 Promise.resolve(promise) 解决的承诺,并且根本没有对所述承诺做任何事情。

标签: javascript ecmascript-6 es6-promise es6-generator


【解决方案1】:

不,不能将参数传递给next

function* generateItems() { /* ... */ }
for (var item of generateItems()) {
   console.log(item);
}

大部分的缩写

function* generateItems() { /* ... */ }
var iterator = generateItems()[Symbol.iterator]();
do {
  const result = iterator.next();
  if (result.done) break;
  const item = result.value;

  console.log(item);
} while (true);

除非缺少一些 try/catch 包装器。您可以看到 in the spec here 调用 .next 时不带任何参数:

让 nextResult 是 ?调用(iteratorRecord.[[NextMethod]], iteratorRecord.[[Iterator]], « »).

例如

iterator.next.apply(iterator, []);

使用空参数数组调用next()

【讨论】:

  • 优秀的答案!
猜你喜欢
  • 2015-04-28
  • 2015-09-23
  • 1970-01-01
  • 1970-01-01
  • 2015-10-26
  • 2014-06-30
  • 1970-01-01
  • 2017-05-07
  • 2018-02-18
相关资源
最近更新 更多