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

如何修改JavaScript串行异步函数方法以按序返回所有执行结果?

问题

我有一个接收异步/同步函数数组的方法,它会按照输入顺序串行(而非并行)调用每个函数。示例代码如下:

const sleep = (delay) => new Promise((r) => setTimeout(r, delay))

const fn1 = async () => {
  await sleep(2000)
  console.log('fn1')
  return 'fn1'
}

const fn2 = async () => {
  await sleep(3000)
  console.log('fn2')
  return 'fn2'
}

const fn3 = async () => {
  await sleep(1000)
  console.log('fn3')
  return 'fn3'
}

const fn4 = () => {
  console.log('fn4')
  return 'fn4'
}

function serializeAsyncFns(fns) {
  return fns.reduce(
    (promise, fn) => promise.then(() => fn()),
    Promise.resolve()
  )
}

serializeAsyncFns([fn1, fn2, fn3, fn4])

// fn1 -> fn2 -> fn3 -> fn4

但当前serializeAsyncFns返回的Promise仅会解析为输入列表中最后一个函数的返回值,即fn4。能否修改该方法,使其返回的Promise解析为所有函数的返回值组成的数组,且顺序与输入顺序一致?例如返回['fn1', 'fn2', 'fn3', 'fn4']。

Promise.all无法满足需求,因为它会并行触发所有Promise。

解决方案

只需要在累积过程中保存每一步的返回值即可,修改后的serializeAsyncFns函数如下:

function serializeAsyncFns(fns) {
  return fns.reduce(
    (promise, fn) => promise.then(results => {
      const result = fn();
      // 统一处理同步/异步函数的返回值,确保以Promise形式处理
      return Promise.resolve(result).then(res => [...results, res]);
    }),
    Promise.resolve([])
  )
}

说明

  1. 初始累积值改为Promise.resolve([]),即以空数组作为结果的起点;
  2. 在then回调中,先获取已有的结果数组results,调用目标函数后将返回值转为Promise(兼容同步函数的直接返回值),再把新结果追加到数组末尾;
  3. 最终返回的Promise会解析为按调用顺序排列的所有函数返回值数组。

调用修改后的函数:serializeAsyncFns([fn1, fn2, fn3, fn4]).then(console.log),会输出['fn1', 'fn2', 'fn3', 'fn4'],同时保持原有的串行执行顺序。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 15:25:19