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

Node.js asyncAuto场景下Callback was already called报错如何解决

Node.js async库回调重复调用问题解决方案

问题根因

你使用的async.js库的asyncAuto方法存在隐式规则:如果任务函数返回了thenable对象(Promise、类Promise实例),async会自动将该对象的执行结果作为任务完成的结果,隐式调用一次任务回调。
你在代码中使用return cbk(null, result)的写法,会将cbk函数的返回值直接作为任务函数的返回值。当进入!args.is_table分支时,cbk调用后的返回值刚好是thenable对象,就会触发async的自动回调逻辑,等于你手动调用一次cbk、async自动调用一次,就触发了Callback was already called报错。
而走else分支时cbk返回值不是thenable,所以不会触发隐式调用,运行正常。

修复方案

方案1:调整回调调用写法(成本最低)

不要在调用回调时直接return其返回值,改为调用回调后单独return,切断隐式触发的条件:

allForwards: ['forwards', ({forwards}, cbk) => {
  if (!args.is_table) {
    cbk(null, {peers: forwards.peers});
    return;
  }

  const isWideSize = !size || size.get().width > wideSizeCols;

  cbk(null, {
    peers: forwards.peers,
    rows: []
      .concat([notNull([
        'Alias',
        'Earned In',
        'Earned Out',
        'Inbound',
        'Outbound',
        !!isWideSize ? 'Public Key' : null,
      ]).map(n => !args.is_monochrome ? bold(n) : n)])
      .concat(forwards.peers.map(peer => {
        return notNull([
          chartAliasForPeer({
            alias: peer.alias,
            icons: peer.icons,
            is_disconnected: peer.is_disconnected,
            is_forwarding: peer.is_forwarding,
            is_inactive: peer.is_inactive,
            is_pending: peer.is_pending,
            is_private: peer.is_private,
            public_key: peer.public_key,
          }).display,
          formatTokens({
            is_monochrome: args.is_monochrome,
            tokens: peer.liquidity_outbound,
          }).display,
          !!isWideSize ? peer.public_key : null,
        ]);
      })),
  });
  return;
}],

方案2:改用async/await写法(更易维护)

async.js的新版本已经原生支持async函数作为任务执行体,不需要手动调用回调,从根源上避免重复调用问题:

allForwards: ['forwards', async ({forwards}) => {
  if (!args.is_table) {
    return {peers: forwards.peers};
  }

  const isWideSize = !size || size.get().width > wideSizeCols;
  return {
    peers: forwards.peers,
    rows: []
      .concat([notNull([
        'Alias',
        'Earned In',
        'Earned Out',
        'Inbound',
        'Outbound',
        !!isWideSize ? 'Public Key' : null,
      ]).map(n => !args.is_monochrome ? bold(n) : n)])
      .concat(forwards.peers.map(peer => {
        return notNull([
          chartAliasForPeer({
            alias: peer.alias,
            icons: peer.icons,
            is_disconnected: peer.is_disconnected,
            is_forwarding: peer.is_forwarding,
            is_inactive: peer.is_inactive,
            is_pending: peer.is_pending,
            is_private: peer.is_private,
            public_key: peer.public_key,
          }).display,
          formatTokens({
            is_monochrome: args.is_monochrome,
            tokens: peer.liquidity_outbound,
          }).display,
          !!isWideSize ? peer.public_key : null,
        ]);
      })),
  };
}],

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.23 23:45:09