捕获 JavaScript 迭代器的返回值

cyb*_*xae 5 javascript iterator

考虑以下迭代器。它生成字符串“foo”和“bar”,然后返回“quux”作为返回值。我可以用来Array.from从迭代器中提取收益,但如果我这样做,我将无法读出返回值。返回值不再由迭代器返回,因为Array.from它已经作为协议的一部分接收(并丢弃?)。

const iterator = (function* () {
  yield 'foo'
  yield 'bar'
  return 'quux'
})()
const [foo, bar] = Array.from(iterator)
const quux = // ???
Run Code Online (Sandbox Code Playgroud)

Array.from我能想到的唯一解决方案是编写一个间谍程序来监视迭代并将返回值存储到预定义变量中作为丢弃返回值之前的副作用。是否有更好的替代方法来访问返回值?

let quux
const spy = function* (i) { /* extract return value from i and store it to quux */ }
const [foo, bar] = Array.from(spy(iterator))
Run Code Online (Sandbox Code Playgroud)

Che*_*yDT 3

你是对的 - 当迭代器next函数返回时{ done: true, value: 'whatever' },该值会被默默地丢弃。

正如您已经说过的,您可以编写一个包装函数(如果您愿意,也可以编写一个类)。但是,您可以将最后一个值转换为常规迭代值,而不是将其保存到外部变量。

例如:

function* yieldFinal (iterator) {
  let done, value
  do {
    ({ done, value } = iterator.next())
    yield value
  } while (!done)
}

const iterator = (function* () {
  yield 'foo'
  yield 'bar'
  return 'quux'
})()

const [foo, bar, quux] = Array.from(yieldFinal(iterator))

console.log(foo, bar, quux)
Run Code Online (Sandbox Code Playgroud)

(注意:如果没有明确的返回值,那么您将获得undefined最后一个值。)

但是,问题是,为什么你需要花这么大的力气呢?return 'quux'你可以不用写作yield 'quux'; return来实现同样的事情,而无需经历所有的困难......