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

如何为返回回调的函数设置超时?解决回调未触发时Promise挂起问题

给回调式函数添加Promise超时机制

我来帮你把这个逻辑补全并拆解清楚,核心就是给依赖回调的函数套一层带超时控制的Promise,避免回调一直不触发导致Promise永远pending的问题。

先给你完整的实现代码:

const mockCliAsync = (argv, stdio, timeout) => {
  return new Promise((resolve, reject) => {
    let timedout = false;
    // 设置超时定时器:到点就标记超时、终止操作并reject
    const timeoutTimer = setTimeout(() => {
      timedout = true;
      kill(); // 这里假设kill是终止原mockCli操作的函数,比如杀掉子进程
      reject(new Error(`操作超时,已在${timeout}ms后终止`));
    }, timeout);

    // 调用原回调式函数
    const kill = mockCli(argv, stdio, (error, result) => {
      // 如果已经超时,就忽略后续回调逻辑
      if (timedout) return;

      // 没超时的话先清除定时器,避免触发超时逻辑
      clearTimeout(timeoutTimer);

      // 根据回调结果处理Promise
      if (error) {
        reject(error);
      } else {
        resolve(result);
      }
    });
  });
};

关键细节拆解

  • 超时看门狗:setTimeout就是我们的超时触发器,到指定时间后会立刻标记timedout状态,调用kill()终止原操作(比如如果mockCli是启动子进程的命令,kill就是杀掉进程),然后reject Promise,避免它一直挂着。
  • 防重复处理:timedout变量很重要,因为有时候超时触发后,原回调可能还会延迟执行,这时候我们要直接忽略回调的结果,防止已经reject的Promise再次被resolve/reject,导致报错。
  • 清理定时器:当回调正常触发时,一定要先调用clearTimeout(timeoutTimer),把超时定时器清掉,不然定时器到点还是会触发,造成不必要的操作。

使用示例

你可以这样调用这个异步函数,用try/catch捕获超时或其他错误:

async function runCli() {
  try {
    const result = await mockCliAsync(['build', '--mode=prod'], 'inherit', 10000); // 10秒超时
    console.log('操作成功:', result);
  } catch (err) {
    console.error('操作失败:', err.message);
  }
}

runCli();

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 11:51:56