如何仅在特定函数执行完成后返回响应?Promise实现失败求助
如何确保异步请求完成后再返回响应?
首先得指出你原来代码的核心问题:request是回调式的异步操作,你在循环发起请求后立刻就调用了resolve(resp),这时候所有请求还没执行完,resp里的数据根本没被填充,所以Promise提前完成了,自然得不到正确结果。而且原代码里如果某个请求返回空数据,直接发送204响应还会导致后续请求回调执行时重复发送响应,引发错误。
下面给你两种可行的实现方式,都是基于Promise来正确等待所有异步请求完成:
方法一:用Promise封装请求 + Promise.all
首先把单个request调用封装成Promise,这样就能用Promise.all来等待所有请求完成:
// 封装单个deal的请求为Promise function fetchDeal(dealId, auth) { return new Promise((resolve, reject) => { const link = `https://api.cortellis.com/api-ws/ws/rs/deals-v2/deal/${dealId}?fmt=json`; const options = { method: 'GET', uri: link, auth: auth, }; request(options, function(error, response, body) { if (error) { reject(error); // 请求失败时抛出错误 return; } const bodyData = JSON.parse(body).dealRecordOutput; if (bodyData.length === 0) { resolve(null); // 空数据时返回null,后续统一处理 } else { // 只返回需要的字段,简化后续处理 resolve({ type: bodyData.Type, status: bodyData.Status }); } }); }); } // 生成所有请求的Promise数组 const dealPromises = deals.map(dealId => fetchDeal(dealId, auth)); // 等待所有请求完成 Promise.all(dealPromises) .then(results => { // 过滤掉空数据的结果 const validResults = results.filter(result => result !== null); // 如果所有结果都是空的,返回204 if (validResults.length === 0) { return res.status(204).json({ data: [] }); } // 整理成需要的响应格式 const resp = { type: validResults.map(r => r.type), status: validResults.map(r => r.status) }; res.status(200).json({ data: resp }); }) .catch(error => { // 处理请求中的错误(比如网络问题、API报错) res.status(500).json({ error: '处理请求时发生错误' }); next(error); });
方法二:用async/await简化代码
如果你的环境支持ES8+,用async/await可以让代码更易读,逻辑更清晰:
// 同样先封装单个请求的Promise function fetchDeal(dealId, auth) { return new Promise((resolve, reject) => { const link = `https://api.cortellis.com/api-ws/ws/rs/deals-v2/deal/${dealId}?fmt=json`; const options = { method: 'GET', uri: link, auth: auth, }; request(options, function(error, response, body) { if (error) { reject(error); return; } const bodyData = JSON.parse(body).dealRecordOutput; if (bodyData.length === 0) { resolve(null); } else { resolve({ type: bodyData.Type, status: bodyData.Status }); } }); }); } // 用async函数处理所有请求 async function handleDealsRequest() { try { const dealPromises = deals.map(dealId => fetchDeal(dealId, auth)); const results = await Promise.all(dealPromises); const validResults = results.filter(result => result !== null); if (validResults.length === 0) { return res.status(204).json({ data: [] }); } const resp = { type: validResults.map(r => r.type), status: validResults.map(r => r.status) }; res.status(200).json({ data: resp }); } catch (error) { res.status(500).json({ error: '处理请求时发生错误' }); next(error); } } // 执行函数 handleDealsRequest();
关键改进点说明:
- 避免提前resolve:通过
Promise.all等待所有异步请求完成后再处理结果,确保resp里的数据是完整的。 - 统一处理空数据:不再在单个请求回调里直接发送响应,而是等所有请求完成后判断是否有有效数据,避免重复发送响应导致的错误。
- 错误处理:通过
catch捕获请求过程中的错误,统一返回500响应,避免程序崩溃。
内容的提问来源于stack exchange,提问作者Ayush
相关产品推荐
相关产品推荐

