You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在JavaScript中异步执行耗时函数且不使用setTimeout?

不使用setTimeout实现耗时函数的异步执行

问题背景

现有如下代码,当前执行后输出顺序为 starts..., waiting ends..., ends...,需要修改为 starts..., ends..., waiting ends...,且不能使用setTimeout:

function wait() {
    let a = Date.now()
    while (Date.now() - a < 3000) {
        // 阻塞循环
    }
    console.log('waiting ends...')
}
function start(){
    console.log('starts...')
    wait()
}
function end(){
    console.log('ends...')
}

start()
end()

解决方案

核心思路是利用JavaScript事件循环机制,将wait()放入微任务队列或宏任务队列,让它在当前同步代码(包括end())执行完毕后再运行,避免阻塞主线程。

方案1:Promise + 微任务队列

将wait()挂载到Promise.resolve().then()的回调中,微任务会在同步代码执行完成后立即执行:

function wait() {
    let a = Date.now()
    while (Date.now() - a < 3000) {
        // 阻塞循环
    }
    console.log('waiting ends...')
}
function start(){
    console.log('starts...')
    Promise.resolve().then(wait);
}
function end(){
    console.log('ends...')
}

start()
end()

方案2:requestIdleCallback(宏任务)

requestIdleCallback会在浏览器主线程空闲时触发回调,属于宏任务范畴,同样能实现延后执行:

function wait() {
    let a = Date.now()
    while (Date.now() - a < 3000) {
        // 阻塞循环
    }
    console.log('waiting ends...')
}
function start(){
    console.log('starts...')
    requestIdleCallback(wait);
}
function end(){
    console.log('ends...')
}

start()
end()

方案3:MessageChannel(宏任务)

通过MessageChannel的消息通信机制,将回调加入宏任务队列:

function wait() {
    let a = Date.now()
    while (Date.now() - a < 3000) {
        // 阻塞循环
    }
    console.log('waiting ends...')
}
function start(){
    console.log('starts...')
    const channel = new MessageChannel();
    channel.port1.onmessage = wait;
    channel.port2.postMessage(null);
}
function end(){
    console.log('ends...')
}

start()
end()

原理说明

JavaScript事件循环的执行顺序为:

  1. 优先执行当前所有同步任务(即start()和end()中的同步打印逻辑)
  2. 同步任务执行完毕后,清空所有微任务队列中的任务
  3. 最后依次执行宏任务队列中的任务

以上方案均通过将wait()放入微/宏任务队列,确保end()的同步代码先执行,从而达到预期的输出顺序。

内容的提问来源于stack exchange,提问作者Li Chen

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 14:47:48