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

JS异步执行机制疑问:主线程async函数与fetch执行顺序解析

JavaScript异步代码行为疑问

以下是测试代码:

async function longTask() {
    let i=0;
    while(true){
            i++
            if(i === 6000000000){
            return "completed a long operation"
        }
    }
}

console.log("start")
fetch('https://jsonplaceholder.typicode.com/todos/1')
      .then(response => response.json())
      .then(json => console.log(json))

longTask().then(result => console.log(result))
console.log("end")

在Chrome控制台的输出为:

start
// 约7-8秒后
end
completed a long operation
{ API调用结果 }

我的疑问:
根据事件循环概念,fetch会被推入宏任务队列,返回Promise的longTask也应进入宏任务队列。我想用longTask模拟比fetch晚resolve但运行在主线程的异步代码,可从输出看,longTask似乎在调用栈执行(因console.log("end")延迟输出)。

  • longTask是否未进入宏任务队列而是被推入调用栈?
  • 若它像普通函数执行,"completed a long operation"应早于"end"输出;若它进入宏任务队列,fetch的回调应更早进入微任务队列,实际却是longTask的回调先执行,请解释其中原理或我的理解误区。

核心原理分析

1. async函数的执行逻辑

async函数本身是同步执行的,只有当内部遇到await或者执行到return时,才会把后续的.then回调推入微任务队列。

你的longTask函数里没有任何await,它会直接在当前调用栈中同步执行这个无限循环,直到i达到6000000000才会return。这就是为什么console.log("end")会被延迟7-8秒才输出——因为longTask()的同步执行阻塞了主线程,直到它执行完,才会继续执行后面的console.log("end")。

2. 输出顺序的深层原因

当longTask执行到return时,会把返回值包装成一个resolved状态的Promise,然后将它的.then回调推入微任务队列。

完整的主线程与队列执行顺序是:

  1. 执行console.log("start") → 输出"start"
  2. 调用fetch:浏览器后台发起网络请求(属于宏任务触发源),同时注册第一个.then回调
  3. 调用longTask():同步执行整个循环,阻塞主线程7-8秒
  4. 循环结束,longTask返回resolved Promise,将它的.then回调推入微任务队列
  5. 执行console.log("end") → 输出"end"
  6. 当前调用栈清空,开始处理微任务队列:先执行longTask的.then回调 → 输出"completed a long operation"
  7. 微任务队列清空后,事件循环处理宏任务队列:此时fetch的网络请求已完成,对应的回调被执行,触发第一个.then(解析response),response.json()返回的Promise又会将其回调推入微任务队列,最终输出API返回的JSON对象。

3. 你的理解误区

  • 误以为async函数调用会直接进入宏任务队列,但实际上async函数的调用是同步的,只有它内部的异步逻辑(比如await)或者返回Promise后的.then回调才会进入微任务队列。
  • fetch的网络请求是浏览器发起的异步操作(属于宏任务),但它的.then回调是微任务。不过因为longTask阻塞了主线程,在longTask执行的7-8秒里,浏览器已经完成了网络请求,但主线程被占用时事件循环无法处理任何队列任务,直到longTask执行完、主线程空闲后才会开始处理队列。

内容的提问来源于stack exchange,提问作者Lakshay Dutta

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 15:52:45