async函数forEach循环调用Xrm.WebApi最终返回空值修复求助
代码问题分析
Array.prototype.forEach不支持异步等待,即使在外部加了await,也不会等待forEach内部的异步操作执行完成,函数会直接执行后续逻辑,此时异步请求还没返回结果,自然拿不到值。Xrm.WebApi.online.retrieveRecord本身返回的是Promise对象,没有加await就直接赋值给name,拿到的不是接口返回的数据,只是Promise实例,自然读取不到对应的属性。- 原逻辑里结果赋值和push操作写在了forEach循环外面,只会执行一次,就算异步正常返回也只能拿到最后一个请求的结果,不符合拼接所有名称的需求。
修正后代码
async function concatnames(allSelectedRows){ const flightName = []; try { // 用for...of循环替代forEach,支持异步等待 for (const selectedRow of allSelectedRows) { // 处理guid const recordidGuid = selectedRow.getData().getEntity().getEntityReference().id.replace(/[{}]/g, ''); // 等待接口返回结果 const name = await Xrm.WebApi.online.retrieveRecord("crd80_flightplanevent", recordidGuid, "?$select=_crd80_learnerflight_value"); const resultOutCome = name["_crd80_learnerflight_value@OData.Community.Display.V1.FormattedValue"]; console.log(resultOutCome); flightName.push(resultOutCome); } } catch (error) { DisplayError(error); } return flightName; }
并发优化版本(请求数量较多时推荐)
如果需要提升请求效率,可以用Promise.all一次性发起所有请求,等所有请求返回后再统一处理:
async function concatnames(allSelectedRows){ try { // 先收集所有请求的Promise实例 const requestPromises = allSelectedRows.map(selectedRow => { const recordidGuid = selectedRow.getData().getEntity().getEntityReference().id.replace(/[{}]/g, ''); return Xrm.WebApi.online.retrieveRecord("crd80_flightplanevent", recordidGuid, "?$select=_crd80_learnerflight_value"); }); // 等待所有请求执行完成 const results = await Promise.all(requestPromises); // 统一提取目标字段返回 return results.map(name => name["_crd80_learnerflight_value@OData.Community.Display.V1.FormattedValue"]); } catch (error) { DisplayError(error); return []; } }
内容的提问来源于stack exchange,提问作者Martin Hutchins
相关产品推荐
相关产品推荐

