我有一个生成器,在其他操作中,查询数据库,如
function* current(db) {
const items = await db.collection('...').find({ ... });
for (const item of items)
if (...) yield item;
}
这是无效的语法。使用承诺并从then
屈服也是不可能的。
那我该怎么办?如何在生成器中使用异步操作?
答案 0 :(得分:11)
Node v10 +(已发布的April 2018和Chrome since v63, as well as Firefox v57中,原生支持在生成器(又名异步生成器)中调用await
。
function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
async function getAsyncData() {
await sleep(1000); // simulate database/network delay...
return [1, 2, 3, 4, 5]; // ...then return some data
}
// async generator
async function* filterAsyncData() {
const items = await getAsyncData(); // await call in generator
for (const item of items)
if (item % 2) yield item;
}
(async function main() {
// for-await syntax
for await (const filteredItem of filterAsyncData())
console.log(filteredItem);
// classic iterator syntax
const fadIt = filterAsyncData();
while (true) {
const result = await fadIt.next(); // note await
if (result.done) break;
console.log(result.value);
}
}());
与常规(非异步)生成器相比,请记住在调用await
之前使用.next()
。另外,新的for-await-of
语法自Node v9.2起可用,并且可以在Node v10中使用而没有任何标志。
对于旧版本的节点(或Jest),您可以使用Babel插件transform-async-generator-functions。
答案 1 :(得分:-1)
您无法将async与生成器功能结合使用。这说你很可能不想在你的情况下使用生成器而只是有一个异步函数:
async function current(db) {
while (true) {
const latest = await db.collection('messages').findOne({}, {
sort: {
timestamp: -1
}
});
return smth;
}
}
在编译async
时,将为您生成生成器。