JavaScript中是否存在线程不安全的可能性?



let arr = [2, 3]
let promiseA = new Promise((resolve)=>{
// await for io
resolve(arr.shift())
})
let promiseB = new Promise((resolve)=>{
// await for io
resolve(arr.shift())
})
let handler = (data)=>{
if(!data){
return console.log("no more")
}
console.log(data)
}
promiseA.then(handler)
promiseB.then(handler)

您好,我有一个关于 javascript 中的一致性的问题。

如果promiseApromiseB一一解决,那就没有问题了。

但是,如果两个 io 操作花费相同的时间,是否有可能使用值2解析promiseApromiseB

@Pointy(在注释中)是正确的,但只是为了形式化它:


promise 正文、消息和事件循环

在两个Promises的正文中运行的任何代码都将在主 JavaScript 事件循环中作为消息执行。

JavaScript 一次运行一条消息,一旦消息在主事件循环中运行,它将在其他任何事情发生之前运行完成:

。它不能被抢占,它将在任何其他代码运行之前完全运行(并且可以修改函数操作的数据)。

setTimeout队列这样的调用messages主事件循环,因此在两个Promises的正文中完成的工作可能跨越多条消息,但每条消息一次运行一条,并在其他任何内容运行之前运行完成。

因此,在每个承诺正文到达此行时:

resolve(arr.shift())

。它将是当前运行的消息,并且"不能被抢占,并将在任何其他代码运行之前完全运行"。

承诺

回调和承诺作业队列

Promise解析时,任何等待Promise的回调都会在 PromiseJobs 队列中排队,这是 ES6 引入的特殊作业队列。

PromiseJobs 队列中的回调在当前消息完成之后和下一条消息开始之前运行,并按顺序一次运行一个,直到队列为空。


所以。。。承诺 A 和承诺 B 是否有可能都以值 2 解析?

不。 两个Promises都以值2解析的可能性为零。

这一行:

resolve(arr.shift())

。是同步的,数组操作和resolve都将作为当前运行的消息的一部分运行完成,然后再运行任何其他代码。

这意味着每个handler回调都保证在 PromiseJobs 中以唯一值排队。


奖金

代码的编写方式,handler保证先在 PromiseJobs 中排队,然后用23排队,无论哪个Promise先解析,所以handler回调保证按该顺序运行,上面的代码在打印3之前总是打印2

最新更新