如何通过Promise实现API轮询校验返回值后执行后续函数
现有代码核心问题
- 所有API请求(
api1、getValue)都是异步函数,直接同步赋值拿到的是Promise对象而非请求返回结果,所以读取.code属性时会抛出undefined错误;如果你的API封装函数没有返回Promise,需要先将回调式的请求封装为返回Promise的形式才能使用await等待结果 - Promise构造函数的回调默认不是异步函数,直接用
await会报错,需要给回调加async关键字修饰,同时做好错误捕获 - 缺少重试次数限制,且首次校验失败就直接调用
reject,不会执行后续重试逻辑,同时校验失败后没有清除定时器,会造成内存泄漏 - 原函数
resolve时没有返回请求结果,链式调用时拿不到前一步的返回值,无法给后续请求传参 getValue异步请求没有等待返回就直接做值比对,判断逻辑永远不生效
修复后代码
const promiseFunc = async (param1, param2) => { // 等待第一个API返回结果 const func1 = await api1(param1).catch(err => { throw new Error('api1调用失败: ' + err) }); if (func1.code !== '200') { throw new Error('api1返回状态异常: ' + func1.code); } // 重试计数配置 let retryCount = 0; const maxRetry = 3; return new Promise((resolve, reject) => { const checkInterval = setInterval(async () => { // 超过最大重试次数直接终止 if (retryCount >= maxRetry) { clearInterval(checkInterval); return reject(new Error('校验次数超限,目标值未就绪')); } try { // 等待校验API返回结果 const check = await getValue(); if (check && check === param2) { clearInterval(checkInterval); // 可根据业务需要调整返回值,供后续调用传参使用 return resolve({ api1Result: func1, checkResult: check }); } retryCount++; } catch (err) { clearInterval(checkInterval); return reject(new Error('校验API调用失败: ' + err)); } }, 5000); }); }
调用示例
推荐async/await写法(逻辑更清晰)
// 可以放在任意async函数内执行,这里用立即执行async函数做示例 (async () => { try { // 第一次调用拿到返回结果 const firstRes = await promiseFunc(myChosenValue1, myChosenValue2); // 用第一次返回的参数传入第二次调用 const secondRes = await promiseFunc(firstRes.api1Result.valueFromFirstExecution1, firstRes.checkResult.valueFromFirstExecution2); console.log('Successfully executed both the functions'); } catch (e) { console.log('执行异常: ', e); } })()
兼容原then链式写法
promiseFunc(myChosenValue1, myChosenValue2) .then(firstRes => { // 用第一步返回的参数传入第二次调用 return promiseFunc(firstRes.api1Result.valueFromFirstExecution1, firstRes.checkResult.valueFromFirstExecution2) }) .then(() => { console.log( 'Successfully executed both the functions' ); }) .catch( e => { console.log( e ); });
内容的提问来源于stack exchange,提问作者s.khan
相关产品推荐
相关产品推荐

