You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.11 09:03:54