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

为何JavaScript中一个Promise函数非阻塞、另一个阻塞代码?Promise.resolve与new Promise的行为差异解惑

为什么nonBlockingCode看起来不阻塞,而blockingCode会阻塞后续代码?

先来看你提供的两段代码:

function blockingCode() {
  return new Promise((resolve, reject) => {
    for (let i = 0; i < 2500000000; i++) {
      // Doing nothing...
    }
    resolve('ping');
  });
}

function nonBlockingCode() {
  return Promise.resolve().then(() => {
    for (let i = 0; i < 2500000000; i++) {
      // Doing nothing...
    }
    return 'pong';
  });
}

// 测试非阻塞代码
console.time('non-blocking');
nonBlockingCode().then((message) => console.log(message));
console.timeEnd('non-blocking');

// 测试阻塞代码(注释状态)
// console.time('blocking');
// blockingCode().then((message) => console.log(message));
// console.timeEnd('blocking');

接下来我会拆解两者的执行逻辑差异,核心在于JavaScript事件循环的同步任务和微任务执行顺序:

1. blockingCode为啥会阻塞?

当你调用blockingCode()时,发生了这些事:

  • new Promise()的构造函数会立刻同步执行你传入的executor回调(就是那个带resolve/reject的函数)
  • 紧接着那个25亿次的for循环就开始跑了——JavaScript是单线程的,同步任务没执行完,主线程根本腾不出手处理后面的代码
  • 等循环终于跑完,才会调用resolve('ping'),把Promise标记为完成状态
  • 这时候,后面的console.timeEnd('blocking')才有机会执行

所以实际运行时,调用blockingCode()后,整个程序会卡住,直到循环结束,才会输出时间和ping——完全阻塞了后续同步代码。

2. nonBlockingCode为啥看起来不阻塞?

调用nonBlockingCode()时,流程是这样的:

  • Promise.resolve()会立刻创建一个已完成的Promise,但它的.then()回调不会马上执行——这个回调会被塞进微任务队列,等待当前所有同步任务执行完毕后才会被处理
  • 所以nonBlockingCode()本身很快就执行完了(只是返回一个Promise,把回调放进队列),主线程立刻转向执行后面的console.timeEnd('non-blocking'),先输出计时结果
  • 等当前所有同步代码(包括console.time、函数调用、console.timeEnd)都跑完,事件循环才会去处理微任务队列里的那个.then()回调,这时候才会开始跑25亿次的for循环
  • 循环结束后返回'pong',触发后续的.then()输出消息

这里要澄清:这个循环本身还是会阻塞主线程的,只是它的执行被推迟到了当前同步代码之后,所以看起来没有阻塞console.timeEnd的执行而已。

3. 解答你的核心疑惑:Promise.resolve和new Promise的差异?

你说的没错,两者最终都会生成一个已完成的Promise,但差异在于代码的执行时机:

  • new Promise(executor)里的executor函数是同步执行的,所以里面的大循环会立刻抢占主线程
  • Promise.resolve().then(callback)里的callback是微任务,会被放到队列排队,等当前同步任务全部结束才会执行

这下应该能理清逻辑了吧?

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.01 00:37:31