使用Promise等待map遍历调用DialogFlow完成后打印日志的问题求解
问题根因
你的代码有两个核心问题导致表现不符合预期:
map遍历中调用detectIntentText时没有返回它的Promise实例,导致promises数组中所有元素都是undefined,Promise.all会直接决议,不会等待异步请求执行完成,所以打印会提前触发,结果都是空值。detectIntentText没有把处理好的结果返回,即使Promise正常执行,Promise.all拿到的结果也是空的。
基础修复代码
首先修改调用部分的代码:
const writeToExcel = []; // map回调中直接返回detectIntentText执行后的Promise const promises = xlData.map(data => detectIntentText(data.QUESTION)); Promise.all(promises).then(results => { // results即为所有请求的返回结果,无需依赖外部writeToExcel变量也可直接使用 console.log(results); console.log(writeToExcel); })
然后修改detectIntentText函数,末尾新增return语句:
async function detectIntentText(userText) { const sessionId = Math.random().toString(36).substring(7); const sessionPath = client.projectLocationAgentSessionPath( projectId, location, agentId, sessionId ); console.info(sessionPath); const request = { session: sessionPath, queryInput: { text: { text: userText, }, languageCode, }, }; const [response] = await client.detectIntent(request); let intent = ""; for (const message of response.queryResult.responseMessages) { if (message.text) { // 原有逻辑保留 } } if (response.queryResult.match.intent) { intent = response.queryResult.match.intent.displayName; } const jsonToWrite = { CX_QUESTION: userText, INTENT: intent } writeToExcel.push(jsonToWrite); return jsonToWrite; // 新增返回结果 }
1000条数据高并发场景优化
如果直接并发1000个请求,大概率会触发Google DialogFlow的API频率限制,返回429错误,建议增加并发控制,以下是无需第三方库的并发控制实现:
// 并发控制函数,limit为最大同时请求数 async function limitConcurrency(taskList, limit) { const resultList = []; const executing = []; for (const task of taskList) { const p = Promise.resolve().then(() => task()); resultList.push(p); if (taskList.length >= limit) { const e = p.then(() => executing.splice(executing.indexOf(e), 1)); executing.push(e); if (executing.length >= limit) { await Promise.race(executing); } } } return Promise.all(resultList); } // 调用示例 const tasks = xlData.map(data => () => detectIntentText(data.QUESTION)); // 最大并发数可根据你的DialogFlow配额调整,默认配额建议设为10即可 limitConcurrency(tasks, 10).then(results => { console.log(results); // 直接用results写入Excel即可 })
内容的提问来源于stack exchange,提问作者newPHPDev
相关产品推荐
相关产品推荐

