如何为返回回调的函数设置超时?解决回调未触发时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
相关产品推荐
相关产品推荐

