Javascript 这个for循环如何无序地执行其迭代器?
我在Javascript 这个for循环如何无序地执行其迭代器?,javascript,node.js,Javascript,Node.js,我在async函数中使用for循环,循环中包含wait。从我读到的内容来看,for循环应该可以很好地处理await,但似乎有一些不寻常的行为我不理解 考虑所描述的func,将其简化为场景的基本要素: let counter = 0; module.exports = async () => { console.log("processing iteration", counter); // just here as // a sanity check to make sure
async
函数中使用for
循环,循环中包含wait
。从我读到的内容来看,for循环应该可以很好地处理await
,但似乎有一些不寻常的行为我不理解
考虑所描述的func,将其简化为场景的基本要素:
let counter = 0;
module.exports = async () => {
console.log("processing iteration", counter); // just here as
// a sanity check to make sure multiple funcs aren't running
// concurrently to produce the out-of-order for loop iteration
counter++;
let keys = [... some array here ...]
for (let i = 0; i < keys.length; i++) {
let key = keys[i];
console.log("processing iteration: [", counter, "] index: [", i, "]")
if (keys[key] === false) {
break;
} else {
if (Array.isArray(keys[key])) {
let x = await doStuff(parseInt(key));
// as suggested in an answer, I tried assigning the result
// to a variable to create a closure, but nothing changes
// in the output
doOtherStuff(parseInt(key));
delete keys[key];
}
}
}
}
但是如果我确实使用了await
,它需要用于按顺序完成这些异步任务(doStuff
任务涉及数据库读取,因此我无法使它们同步),那么疯狂就会发生
具体来说,一旦使用了await
,首先调用函数时,它的工作原理与预期基本相同:
processing iteration 15
processing iteration: [ 16 ] index: [ 0 ]
processing iteration: [ 16 ] index: [ 1 ]
processing iteration: [ 16 ] index: [ 2 ]
processing iteration: [ 16 ] index: [ 3 ]
processing iteration: [ 16 ] index: [ 4 ]
processing iteration: [ 16 ] index: [ 5 ]
processing iteration: [ 16 ] index: [ 6 ]
processing iteration: [ 16 ] index: [ 7 ]
processing iteration: [ 16 ] index: [ 8 ]
processing iteration: [ 16 ] index: [ 9 ]
processing iteration: [ 16 ] index: [ 10 ]
processing iteration: [ 16 ] index: [ 11 ]
processing iteration: [ 16 ] index: [ 12 ]
processing iteration: [ 16 ] index: [ 13 ]
但是随着模拟的进行,这个函数会被调用很多次,而那些日志显示它在第16次迭代时运行良好,只要内部发生了变化doStuff
(更难解释内部到底发生了什么变化,但一旦满足某些条件,内部就会开始进行其他处理和循环)迭代器开始执行多次:
processing iteration 147
processing iteration: [ 148 ] index: [ 0 ]
processing iteration: [ 148 ] index: [ 1 ]
... something changes here with what's happening inside of doStuff ..
processing iteration: [ 148 ] index: [ 1 ]
processing iteration: [ 148 ] index: [ 1 ]
processing iteration: [ 148 ] index: [ 1 ]
processing iteration: [ 148 ] index: [ 1 ]
processing iteration: [ 148 ] index: [ 1 ]
processing iteration 148
processing iteration: [ 149 ] index: [ 0 ]
然后不仅索引重复,而且在以下func迭代计数中,循环的开始按循环顺序进行迭代:
processing iteration 148
processing iteration: [ 149 ] index: [ 0 ]
processing iteration 149
processing iteration: [ 150 ] index: [ 0 ]
processing iteration: [ 150 ] index: [ 2 ]
processing iteration: [ 150 ] index: [ 2 ]
processing iteration: [ 150 ] index: [ 2 ]
processing iteration: [ 150 ] index: [ 2 ]
processing iteration: [ 150 ] index: [ 1 ]
processing iteration: [ 150 ] index: [ 2 ]
processing iteration 150
processing iteration: [ 151 ] index: [ 0 ]
processing iteration 151
processing iteration: [ 152 ] index: [ 0 ]
processing iteration: [ 152 ] index: [ 2 ]
processing iteration 152
processing iteration: [ 153 ] index: [ 0 ]
对于循环for
和async
和await
是否有一些我根本无法理解的东西,只要看一下这段代码的简略版本就可以解释?一定有一些我遗漏了,因为在我看来,使用await时,对于那些f或
循环迭代器以按顺序打印
如果需要,我将发布完整版本的代码,包括在doStuff
中发生的事情,我只是对其进行了删节,以尽可能简洁地回答问题,除非需要更多的细节。注意9000个日志,以及发生这种情况时索引的分解。外部函数是异步的,因此它们被放在事件循环中nd将与事件循环中的等待调用混合。
因此,等待之后的下一次迭代将在计数器的值已经递增后使用计数器的值。
还请注意,输出在经过1秒之后发生
关键之处在于等待类似于一个“”,它使它退出函数并产生一个承诺,并将其放入事件循环中
因此,可能发生的情况是,当一个等待被命中时,执行被延迟,因此计数器在等待位置等待事件循环时被更改
for(让i=0;inew Promise(r=>Math.random(){}
var计数器2=0
设计数器=0;
module.exports=async()=>{
log(“正在处理迭代”,计数器);//如下所示
//一个健全的检查,以确保多个函数没有运行
//同时为循环迭代生成无序
计数器++;
控制台日志(计数器2)
设keys=[1,2,6,6,1,6[1],[1],10]
for(设i=0;i
如果这里没有一些基本的、立即明显的行为解释,请告诉我,我会发布未删节的代码,包括在doStuff
wow中发生的事情,这真的很棘手。通过将for循环转换为递归函数调用,在con之前等待每个承诺完成,可以解决这个问题吗tinuing?这实际上构成了“按预期工作”,因为async/await应该延迟执行,并且“已修复”必须取决于您尝试执行的操作。当导出的函数是异步的且调用代码没有等待时,您不应该依靠全局变量计数器来跟踪执行流顺序。基本上,您唯一应该“依赖”的是“承诺”对于变量计数器
,如果等待对变量计数器
起作用的所有调用,则它将达到10
(或它应该得到的任何结果)。全局问题请参见第二个示例,在这两个示例之间执行不会延迟,因为对module.exports()的每个调用在继续下一个调用之前等待。其要点是一路异步到“顶部”。如果我有多个对Promise wrapped或async函数的调用,如果我没有显式地等待它们,我应该预期它们可能会被延迟,并且它们的Promise解析的顺序可能会有所不同。请注意,第二个示例是如何在1秒内成批解析的,而不是像第一个示例那样立即完成并执行所有这些函数在等待后1秒钟后,值为9000。感谢您的时间和帮助。这解决了我的问题
processing iteration 148
processing iteration: [ 149 ] index: [ 0 ]
processing iteration 149
processing iteration: [ 150 ] index: [ 0 ]
processing iteration: [ 150 ] index: [ 2 ]
processing iteration: [ 150 ] index: [ 2 ]
processing iteration: [ 150 ] index: [ 2 ]
processing iteration: [ 150 ] index: [ 2 ]
processing iteration: [ 150 ] index: [ 1 ]
processing iteration: [ 150 ] index: [ 2 ]
processing iteration 150
processing iteration: [ 151 ] index: [ 0 ]
processing iteration 151
processing iteration: [ 152 ] index: [ 0 ]
processing iteration: [ 152 ] index: [ 2 ]
processing iteration 152
processing iteration: [ 153 ] index: [ 0 ]