首页 > 解决方案 > javascript回调中的实际运行时是什么

问题描述

我正在尝试理解 JS 回调。在下面的示例中,A 是在 100 毫秒后执行还是立即执行?

每个 A、B、C 执行的实际时间是多少?0 毫秒:“A”(或 100 毫秒?) 100 毫秒:“C”,100 毫秒:“B”

function wait(ms) {
    let waitUntil = Date.now() + ms
    while (Date.now() < waitUntil) { continue }
}

document.querySelector('#start-button').onclick = () => {
    console.log('A')

    setTimeout(() => {
      console.log('B')
    }, 50)

    wait(100)

    console.log('C')
}

如果将其修改为:

function wait(ms) {
    let waitUntil = Date.now() + ms
    while (Date.now() < waitUntil) { continue }
}

document.querySelector('#start-button').onclick = () => {
    console.log('A')

    setTimeout(() => {
      console.log('B')
    }, 150) // 150ms instead of 50ms

    wait(100)

    console.log('C')
}

实际运行时间是多少?是0ms:A 100ms:C 150ms:B(或100ms+150ms=250ms)

标签: javascriptasynchronous

解决方案


我冒昧地为您提供了可运行的功能。我还大幅增加了延迟以更清楚地说明这一点。您可以看到,在单击开始按钮后,实际上直到整个 lambda onclick 函数完成其执行后,您才能将任何输出输出到控制台,直到阻塞线程的等待调用完成后才能执行此操作。但是,A 日志语句确实首先执行,并且其时间戳比 C 语句早了整整 2 秒。

有趣的是,B 语句的 setTimeout 延迟实际上被忽略并被阻塞线程的等待语句所取代。在等待块完成后触发该函数时会引入 <10ms 的小延迟。但是,如果您将等待延迟降低到小于给定 setTimeout 的延迟,它会在给定的时间延迟之后执行。

所以时间看起来是这样的:

A: 0, but it's printed after the wait delay
C: the wait delay
B: the wait delay + <10ms

还值得注意的是,块的执行时间可能会在这里或那里增加额外的毫秒,正如您通过运行块所看到的那样。如果您的延迟是 200 毫秒,那么它很可能会显示 201 毫秒的日志时间。如果块变得更复杂并且需要更长的执行时间,这种效果将变得更加明显。

function wait(ms) {
    let waitUntil = Date.now() + ms
    while (Date.now() < waitUntil) { continue }
}

document.querySelector('#start-button').onclick = () => {
    console.log('A', Date.now())

    setTimeout(() => {
      console.log('B', Date.now())
    }, 500)

    wait(2000)

    console.log('C', Date.now())
}
<button id="start-button">Start</button>

这是较短的等待电话。

A: 0, but it's printed after the wait delay
C: the wait delay
B: 500ms

function wait(ms) {
    let waitUntil = Date.now() + ms
    while (Date.now() < waitUntil) { continue }
}

document.querySelector('#start-button').onclick = () => {
    console.log('A', Date.now())

    setTimeout(() => {
      console.log('B', Date.now())
    }, 500)

    wait(200)

    console.log('C', Date.now())
}
<button id="start-button">Start</button>


推荐阅读