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

技术问询:四种JavaScript ES6 Promise写法有何区别?

四种ES6 Promise写法的核心区别

嘿,这几个写法乍一看差不多,但实际运行逻辑和Promise链的行为差异很大,咱们逐个拆解明白:


1. doSomething().then(function () { return doSomethingElse(); });

这个写法里,doSomething完成(状态变为resolved)后,会执行匿名回调函数:

  • 回调里调用doSomethingElse(),并返回它的Promise实例
  • 因此,这个then会等待doSomethingElse的Promise完成,才会推进到下一个链式调用(如果有的话)
  • 注意:如果doSomething有返回值,这个匿名函数没接收参数的话,doSomethingElse拿不到这个值——比如如果doSomethingElse需要依赖doSomething的结果,得写成function(result) { return doSomethingElse(result); }

举个实际运行的例子:

function doSomething() {
  return new Promise(resolve => setTimeout(() => resolve('doSomething done'), 1000));
}
function doSomethingElse() {
  return new Promise(resolve => setTimeout(() => resolve('doSomethingElse done'), 1000));
}

doSomething()
  .then(() => { return doSomethingElse(); })
  .then(result => console.log(result)); // 会在2秒后输出"doSomethingElse done"

2. doSomething().then(function () { doSomethingElse(); });

和第一个写法的核心区别是没有返回doSomethingElse()的Promise:

  • doSomething完成后执行匿名回调,调用doSomethingElse()但不返回任何值(默认返回undefined)
  • Promise规则里,then的回调如果返回非Promise值,会被包装成一个立即resolved的Promise(值为undefined)
  • 所以下一个链式调用会立刻执行,完全不等doSomethingElse的异步操作完成
  • 这是常见的bug点——如果你想等待doSomethingElse,却忘了return它的Promise

例子:

doSomething()
  .then(() => { doSomethingElse(); })
  .then(result => console.log(result)); // 1秒后输出undefined,而doSomethingElse还在后台运行

3. doSomething().then(doSomethingElse());

这个写法是最容易踩坑的,因为它犯了一个低级错误:

  • doSomethingElse()是立即执行的,根本不会等doSomething完成!
  • then方法需要接收的是一个函数(onFulfilled回调),但这里直接执行了doSomethingElse(),把它的返回值传给了then
    • 如果doSomethingElse()返回的不是函数,then会把这个参数忽略(替换成默认的恒等函数,直接传递上一个Promise的值)
    • 哪怕doSomethingElse()返回Promise,then也不会把它当成回调,而是直接处理这个Promise的结果

例子:

// 执行这行代码时,doSomethingElse会立刻被调用,然后才开始执行doSomething
doSomething()
  .then(doSomethingElse())
  .then(result => console.log(result)); // 先触发doSomethingElse的执行,1秒后输出"doSomething done"

4. doSomething().then(doSomethingElse);

这是最简洁且正确的写法之一,和第一个写法的效果类似,但更优雅:

  • 直接把doSomethingElse函数引用传给then,当doSomething完成后,会自动调用doSomethingElse,并把doSomething的resolved值作为参数传给它
  • 如果doSomethingElse返回Promise,then会等待这个Promise完成,再推进链式调用
  • 相比第一个写法,它不需要额外的匿名函数包裹,还能自动传递上一个Promise的结果,代码更简洁

例子:

function doSomethingElse(value) {
  console.log('收到上一步的值:', value);
  return new Promise(resolve => setTimeout(() => resolve('doSomethingElse done'), 1000));
}

doSomething()
  .then(doSomethingElse)
  .then(result => console.log(result)); 
// 1秒后输出"收到上一步的值: doSomething done",再过1秒输出"doSomethingElse done"

总结一下关键点:

  • 要等待异步操作,必须在then的回调里返回对应的Promise
  • 传给then的必须是函数引用,不能是立即执行的函数调用(除非你故意要提前执行)
  • 传递函数引用时,上一个Promise的结果会自动作为参数传入回调函数

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 07:33:23