Dynamics 365中Xrm.WebApi.retrieveMultipleRecords异步返回值问题求助
解决Xrm.WebApi.retrieveMultipleRecords异步调用导致返回值为空的问题
你的问题核心在于异步操作的执行顺序——Xrm.WebApi.retrieveMultipleRecords是异步API,你的getInvoiceTemplates函数在调用它之后会立刻执行完毕并返回,此时success回调还没触发,所以你拿到的结果自然是空的。你在success回调里return的数组,只是回调函数的返回值,并不会成为getInvoiceTemplates的返回值。
下面是具体的修复方案:
1. 让getInvoiceTemplates返回Promise
修改函数,直接返回Xrm.WebApi.retrieveMultipleRecords的Promise对象,在success回调中处理数据并返回最终数组:
function getInvoiceTemplates() { debugger; var fetchTemplates = "<fetch>"+ " <entity name='invoice' >" + " <attribute name='name' />" + " <attribute name='invoiceid' />" + " <filter type='and' >" + " <condition attribute='ambcust_vorlage_twooption' operator='eq' value='1' />" + " </filter>" + " <order attribute='name' descending='false' />" + " </entity>" + "</fetch>"; fetchTemplates = "?fetchXml=" + encodeURIComponent(fetchTemplates); // 返回异步操作的Promise return Xrm.WebApi.retrieveMultipleRecords("invoice", fetchTemplates).then( function success(result) { var TableContent = []; // 用数组字面量更简洁 for (var i = 0; i < result.entities.length; i++) { var RowContent = {}; // 用||简化null/undefined判断 RowContent["TemplateID"] = result.entities[i].invoiceid || ""; RowContent["TemplateName"] = result.entities[i].name || ""; TableContent.push(RowContent); } return TableContent; }, function (error) { console.error("加载发票模板出错:", error); // 用控制台输出更利于调试 alert("加载发票模板失败,请重试"); throw error; // 传递错误给调用方处理 } ); }
2. 修改对话框中的调用逻辑
原来的同步赋值var TableContent = getInvoiceTemplates()无法等待异步结果,需要改为等待Promise完成后再初始化DevExpress控件:
方案A:使用.then链式调用
<script language="javascript" type="text/javascript"> debugger; Globalize.culture('de-CH'); // 等待模板数据加载完成后初始化DataGrid getInvoiceTemplates().then(function(TableContent) { var dataGridTemplates = $("#TemplateContainer").dxDataGrid({ dataSource: TableContent, selection: { mode: 'single' }, // ... 你的其他控件配置 }); }).catch(function(error) { // 统一处理错误 console.error("初始化DataGrid出错:", error); }); </script>
方案B:使用async/await(更简洁)
如果你的运行环境支持ES2017+(Dynamics 365的现代浏览器环境都支持),可以用async/await让代码看起来像同步执行:
<script language="javascript" type="text/javascript"> debugger; Globalize.culture('de-CH'); // 用立即执行的async函数包裹逻辑 (async function() { try { var TableContent = await getInvoiceTemplates(); var dataGridTemplates = $("#TemplateContainer").dxDataGrid({ dataSource: TableContent, selection: { mode: 'single' }, // ... 你的其他控件配置 }); } catch(error) { console.error("操作出错:", error); alert("加载模板失败,请检查控制台详情"); } })(); </script>
额外提示
- 调试异步代码时,尽量用
console.log/console.error代替alert,能看到更详细的错误信息和变量内容。 - 数组和对象的创建推荐用字面量
[]/{},比new Array()/new Object()更简洁直观。 - 如果你需要在多个地方复用模板数据,可以考虑把加载结果缓存起来,避免重复调用API。
内容的提问来源于stack exchange,提问作者Martin Felber
相关产品推荐
相关产品推荐

