提问人:François Richard 提问时间:1/14/2021 更新时间:1/14/2021 访问量:110
javascript 是否存在异步循环的可变并发问题
Can javascript have mutable concurrency problem with async loop
问:
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 时,从代码中看得有点困难,但 primcipal 仍然保持不变。
我总是这样看:
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();
而且这部分也不能被不同的事件打断,这意味着在设置为下一次调用 someAsyncFunc() 之间发生的一切都是原子发生的。res
因此,在此期间无法填充另一个循环。mutable[res.someKey]
进一步阅读:
- https://developer.mozilla.org/en-US/docs/Web/JavaScript/EventLoop
- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/await
评论