问题描述
let mutableObject = {};
for( ...loop over wtv...) {
const res = await someAsyncFunc();
if(!mutable[res.someKey]) {
mutable[res.someKey] = {}
}
mutable[res.someKey][res.other] = res.value;
}
res.someKey 对许多 res 是通用的,问题是,是否有可能在某个时候 mutable[res.someKey] 被检测为空,实际上它正在由循环中的另一个 res 填充。这可能导致重置( mutable[res.someKey] = {})并跳过其他填充 res 操作。
换句话说,这件事件可能吗?
=> loop1 !mutable[res.someKey] 为空 ...
=> loop2 !mutable[res.someKey] 为空,让我们重置并填充!
=> loop1 ... ,让我们重置和填充 => 我们失去了重置的 loop2 动作
我希望它足够清楚让我知道,提前致谢。
解决方法
如果我理解正确的话,这是不可能的。
JavaScript 通常是单线程的(也有例外,但您没有具体说明,所以我认为您的情况没有什么特别之处)。
在 JavaScript 中,所有代码都在事件内部执行。这些事件被排入事件队列。队列中的事件总是在队列中的下一个事件执行之前完全执行,因为只有一个线程可以执行它们。
使用 async-await 时,从代码中看有点困难,但主要内容仍然保持不变。
我总是这样看:
async-await 在 await
处将函数“切割”成多个部分,但这些部分本身总是在其他任何事情发生之前完整执行。
当函数启动时,下面的代码被执行而不能被不同的事件中断。
let mutableObject = {};
for( ...loop over wtv...) { // first iteration
someAsyncFunc(); // someAsyncFunc is executed but does not "return" yet
然后第一个“事件”因为await
而结束。
当 someAsyncFunc() 返回的 Promise 解决时。它将继续:
const res = // result is written from someAsyncFunc
if(!mutable[res.someKey]) {
mutable[res.someKey] = {}
}
mutable[res.someKey][res.other] = res.value;
}
for( ...loop over wtv...) { // next iteration
someAsyncFunc();
这部分也不能被不同的事件中断,这意味着在 res
被设置为下一次调用 someAsyncFunc() 之间发生的一切都是原子发生的。
因此,在此期间另一个循环无法填充 mutable[res.someKey]
。
进一步阅读: