给定一个像这样的循环:
for await(let line of readFileLineByLine('./long-file.txt')) {
const interestingFacts = await processLine(line);
}
在哪里readFileLineByLine
返回AsyncGenerator,它将在await processLine
返回之前或之后开始处理第二行吗?(假设第二行在processLine
完成之前已准备就绪)
如果没有,那么如何并行化呢?(以便可以同时处理许多行)
您的for await
循环是以下方面的语法糖:
let generator = readFileLineByLine();
while (true) {
let promise = generator.next();
let item = await promise;
if (item.done)
break;
let line = item.value;
await processLine(line)
}
因此,答案是肯定的,readLine(nextLine)
直到processLine(previousLine)
完成才开始。
如果您希望两个函数不相互依赖,则一种选择是使readFileLineByLine
非异步,即只是yield
待定的承诺。正常使用此生成器,附加then(processLine)
到每个诺言,然后等待它们:
let promises = [];
for (let promise of readFileLineByLinePending())
promises.push(promise.then(processLine))
await Promise.all(promises)
这是一个演示:
async function delay(n) {
return new Promise(res => setTimeout(res, n))
}
async function processLine(s) {
console.log('process BEGIN:', s)
await delay(300);
console.log('process END:', s)
}
async function* readFileLineByLine() {
for (let i = 0; i < 6; i++) {
console.log('read BEGIN', i)
await delay(500);
let t = await 'line' + i;
console.log('read END', i)
yield t;
}
}
function* readFileLineByLinePending() {
for (let i = 0; i < 6; i++) {
console.log('readPending BEGIN', i)
let t = delay(500).then(() => {
console.log('readPending END', i);
return 'line' + i;
});
yield t;
}
}
async function main() {
console.time('async gen')
for await(let line of readFileLineByLine())
await processLine(line)
console.log('----------------------------------------')
console.timeEnd('async gen')
console.log('----------------------------------------')
console.time('sync gen')
let promises = [];
for (let promise of readFileLineByLinePending())
promises.push(promise.then(processLine))
await Promise.all(promises)
console.log('----------------------------------------')
console.timeEnd('sync gen')
console.log('----------------------------------------')
}
main().then(() => console.log('done'))
.as-console-wrapper {max-height:100% !important; top:0;}
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句