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
解析?
答案 0 :(得分:0)
@Pointy(在评论中)是正确的,但只是为了使其正式化:
在两个Promises
主体中运行的任何代码都将作为消息在主JavaScript Event Loop中执行。
JavaScript一次运行一条消息,一旦一条消息在主事件循环中运行,它将run to completion发生在其他事情之前:
...它不能被抢占,并且可以在其他任何代码运行之前完全运行(并且可以修改函数操作的数据)。
类似setTimeout
的调用在主事件循环中排入messages
,因此在两个Promises
的主体中完成的工作可能跨越多条消息,但是每条消息在一个时间并在完成其他任何操作之前先完成操作。
因此,在每个承诺主体到达此行时:
resolve(arr.shift())
...它将是当前正在运行的消息,并且“不能被抢占,并且将完全在任何其他代码运行之前运行”。
Promise
解析后,等待Promise
的所有回调都将在PromiseJobs queue中排队,这是ES6引入的特殊作业队列。
在PromiseJobs队列中的回调在当前消息完成之后,下一条消息开始之前运行,并依次运行一次,直到队列为空。
不。两个Promises
都将以值2
进行解析的可能性为零。
此行:
resolve(arr.shift())
...是同步的,并且在运行任何其他代码之前,数组操作和resolve
都将作为当前运行消息的一部分运行完毕。
这意味着确保每个handler
回调都在PromiseJobs中以唯一的值排队。
奖金
保证编写代码的方式handler
首先在2
中排队在PromiseJobs中,然后再在3
之后在PromiseJobs中排队,无论 Promise
首先解析,因此保证handler
回调按该顺序运行,并且上面的代码将始终打印2
,然后再打印3
。