什么决定了要读取Javascript中的行的顺序?

时间:2019-07-02 22:38:21

标签: javascript runtime

此示例在演示中给出了期望这些函数的运行顺序为1、2、3,但实际上为1、3、2。很好奇为什么setTimeout函数将最后运行?

console.log(1)
setTimeout(() => console.log(2), 0)
console.log(3)

2 个答案:

答案 0 :(得分:1)

异步回调与上面传递给setTimeout()的回调一样,会在脚本的主要同步主体运行完毕时放入要调用的队列。

所以顺序是:

console.log(1)
setTimeout() // but not the callback
// put callback in queue
console.log(2)

// take item from queue and run
() => console.log(2)

其结果之一是传递给setTimeout的时间是回调触发前的最短时间。如果主要同步任务花费的时间超过此时间,则回调将延迟触发。

您可以通过运行长时间运行的while循环来演示这一点。 (但请不要在真实代码中执行此操作)

let start = Date.now()
let now = start
let then = now + 3000;
   
// set timer for 100ms
setTimeout(() => console.log("timeout fired ater", Date.now() - start, "milliseconds"), 100)

// slow while loop takes 3000ms
while (now < then){
  now = Date.now()
}
console.log("loop done")

答案 1 :(得分:0)

setTimeout的回调是异步的,因此它可能已被注册触发*,但是要花足够长的时间才能注册console.log(3)到那时为止。

在处理异步代码时,您通常不能保证它将以确切的顺序运行。

*老实说,我不知道setTimeout的内部,这可能取决于反正使用的确切实现。关键是它的回调是异步运行的。