有什么办法可以从yield * asyncIterator
返回吗?
背景:
给定这样的异步迭代器:
const asyncIterator = {
next () {
return new Promise(resolve => setTimeout(() => resolve('next'), 500))
},
return () {
return Promise.resolve('return')
},
[Symbol.asyncIterator] () {
return this
}
}
以下将永远不会调用其
return
方法:async * yieldFromIterator () {
yield 'start'
yield * asyncIterator
}
const yieldingIterator = yieldFromIterator()
console.log(await yieldingIterator.next()) // 'start'
console.log(await yieldingIterator.next()) // 'next'
console.log(await yieldingIterator.return()) // never resolved
这也没有:
async * yieldFromIterator () {
yield 'start'
for await (const result of asyncIterator) {
yield result
}
}
const yieldingIterator = yieldFromIterator()
console.log(await yieldingIterator.next()) // 'start'
console.log(await yieldingIterator.next()) // 'next'
console.log(await yieldingIterator.return()) // never resolved
当然可以做到以下几点:
async * returnIterator () {
yield 'start'
return asyncIterator
}
const returningIterator = returnIterator()
console.log(await returningIterator.next()) // 'start'
console.log(await returningIterator.next()) // 'next'
console.log(await returningIterator.return()) // 'return'
非常感谢你 :)
最佳答案
您的asyncIterator
发生错误:promise must be a result object(实现IteratorResult interface的对象,其形状为{done, value}
)的实现值。但是,您将使用字符串来实现 promise 。
如果更新它以返回结果对象,则将看到返回:
const asyncIterator = {
next () {
return new Promise(resolve => setTimeout(() => resolve({value: 'next', done: false}), 500))
},
return () {
return Promise.resolve({value: 'return', done: true})
},
[Symbol.asyncIterator] () {
return this
}
}
async function * yieldFromIterator () {
yield 'start'
yield * asyncIterator
}
(async function() {
const yieldingIterator = yieldFromIterator()
console.log(await yieldingIterator.next()) // {value: 'start', done: false}
console.log(await yieldingIterator.next()) // {value: 'next', done: false}
console.log(await yieldingIterator.return()) // {value: 'return', done: true}
})().catch(error => {
console.error(error)
})
.as-console-wrapper {
max-height: 100% !important;
}
另外,
asyncIterator
还有另一个问题(不一定是bug):它不继承自%AsyncIteratorPrototype%及其下面的链。从理论上讲,代码可以将方法添加到%AsyncIteratorPrototype%,%IteratorPrototype%等中,而asyncIterator
中将缺少这些方法。通常,异步生成器函数是创建异步迭代器对象的最佳方法(因为异步生成器是异步迭代器),就像非异步生成器函数是创建迭代器的最佳方法一样。您可以从
yield
语法中受益并从标准原型(prototype)中继承。就是说,如果您使用异步生成器函数实现了
asyncIterator
,您将看不到响应该'return'
调用的return
字符串。您需要调用next
,并在return
中使用yieldFromIterator
:const delay = (ms, ...args) => new Promise(resolve => setTimeout(resolve, ms, ...args));
const asyncIterator = (async function*() {
await delay(500);
yield 'next';
return 'return';
})();
async function * yieldFromIterator () {
yield 'start'
return yield * asyncIterator // <=== Added `return`
}
(async function() {
const yieldingIterator = yieldFromIterator()
console.log(await yieldingIterator.next()) // {value: 'start', done: false}
console.log(await yieldingIterator.next()) // {value: 'next', done: false}
console.log(await yieldingIterator.next()) // {value: 'return', done: true}
// Changed to `next` −−−−−−−−−−−−−−^
})().catch(error => {
console.error(error)
})
.as-console-wrapper {
max-height: 100% !important;
}
关于javascript - 如何从 yield 中获得返回*,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/59576490/