[英]is there a probability of thread unsafety in 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 中的并发的问题。
如果promiseA
和promiseB
解决,就没有问题了。
但是,如果两个 io 操作花费相同的时间,那么promiseA
和promiseB
是否有可能以2
的值解析?
@Pointy(在评论中)是正确的,但只是为了将其正式化:
在两个Promises
的主体中运行的任何代码都将作为主 JavaScript 事件循环中的消息执行。
JavaScript 一次运行一条消息,一旦一条消息在主事件循环中运行,它将在其他任何事情发生之前运行完成:
...它不能被抢占,并且会在任何其他代码运行之前完全运行(并且可以修改函数操作的数据)。
调用类似于主事件循环的setTimeout
队列messages
,因此在两个Promises
的主体中完成的工作可能跨越多条消息,但每条消息一次运行一个,并在其他任何运行之前运行到完成。
所以在每个承诺体到达这一行时:
resolve(arr.shift())
...它将是当前正在运行的消息,并且“不能被抢占,并且将在任何其他代码运行之前完全运行”。
当Promise
解析时,任何等待Promise
回调都会在PromiseJobs 队列中排队,这是 ES6 引入的特殊作业队列。
PromiseJobs 队列中的回调在当前消息完成之后和下一条消息开始之前运行,并按顺序一次运行一个,直到队列为空。
不。两个Promises
都以2
值解析的可能性为零。
这一行:
resolve(arr.shift())
...是同步的,数组操作和resolve
都将在任何其他代码运行之前作为当前正在运行的消息的一部分运行完成。
这意味着每个handler
回调都保证以唯一值在 PromiseJobs 中排队。
奖金
代码的编写方式,保证handler
首先在 PromiseJobs 中排队2
,然后在 PromiseJobs 中排队3
,无论哪个Promise
先解析,所以handler
回调保证按该顺序运行,并且上面的代码将总是打印2
打印前3
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.