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

DataTables显示[object promise]而非真实数据问题求助

解决DataTables中显示[object promise]而非实际测试名称的问题

你的问题根源在于DataTables的render函数不支持异步返回值:async函数的返回本质是一个Promise对象,DataTables会直接把这个对象转换成字符串[object promise]显示,不会等待Promise完成后再渲染最终值。虽然你在console.log里能看到正确结果,但那是Promise resolve后的输出,和DataTables的渲染时机不匹配。

下面提供两种可行解决方案:

方案1:预加载并整合数据(推荐,性能更优)

先获取所有测试分类数据,批量获取对应的测试名称并整合,再将处理好的数据传给DataTables,避免在渲染阶段做异步请求:

$(document).ready(async function () {
    // 1. 获取TestCategory基础数据
    const categoryResponse = await $.ajax({
        url: "https://localhost:7136/api/TestCategory",
        type: "GET",
        dataType: "json"
    });
    const categoryData = categoryResponse.data;

    // 2. 收集所有需要查询的测试ID并去重,减少重复请求
    const allTestIds = [];
    categoryData.forEach(item => {
        item.testKit.split(',').forEach(id => {
            if (!allTestIds.includes(id)) allTestIds.push(id);
        });
    });

    // 3. 并行请求所有测试名称,提升请求效率
    const testNamePromises = allTestIds.map(id => 
        $.ajax({
            url: `https://localhost:7136/api/Test/${id}`,
            type: "GET",
            dataType: "json"
        }).then(res => ({ id, name: res.data.testName }))
    );
    const testNameMap = await Promise.all(testNamePromises);
    // 转成键值对,方便快速查找
    const testNameLookup = testNameMap.reduce((map, item) => {
        map[item.id] = item.name;
        return map;
    }, {});

    // 4. 整合数据,把testKit字段替换为对应的名称字符串
    categoryData.forEach(item => {
        item.testKitNames = item.testKit.split(',').map(id => testNameLookup[id]).join(',');
    });

    // 5. 初始化DataTables,直接使用整合后的字段
    table = $('#TblTestCategory').DataTable({
        "order": [],
        "drawCallback": function (settings) {
            var api = this.api();
            var startIndex = api.context[0]._iDisplayStart;
            var counter = startIndex + 1;
            api.column(0, { page: 'current' }).nodes().each(function (cell, i) {
                cell.innerHTML = counter;
                counter++;
            });
        },
        responsive: true,
        data: categoryData,
        "columns": [
            {
                "data": "testKitNames",
                "orderable": false,
                "orderData": [1]
            }
            // 其他列配置...
        ]
    });
});

方案2:在render中手动更新单元格(适合小数据量场景)

如果不想修改初始数据加载逻辑,可以在render里发起异步请求,等Promise完成后手动更新单元格内容,同时避免返回Promise:

$(document).ready(function () {
    table = $('#TblTestCategory').DataTable({
        "order": [],
        "drawCallback": function (settings) {
            var api = this.api();
            var startIndex = api.context[0]._iDisplayStart;
            var counter = startIndex + 1;
            api.column(0, { page: 'current' }).nodes().each(function (cell, i) {
                cell.innerHTML = counter;
                counter++;
            });
        },
        responsive: true,
        "ajax": {
            url: "https://localhost:7136/api/TestCategory",
            type: "GET",
            "dataType": "json",
            "dataSrc": "data",
        },
        "columns": [
            {
                "data": "testKit",
                "orderable": false,
                "orderData": [1],
                "render": function (data, type, row, meta) {
                    // 先显示加载提示,避免显示[object promise]或空白
                    const cell = $(table.cell(meta.row, meta.col).node());
                    cell.text('加载中...');

                    // 异步获取名称后更新单元格
                    generateString(data).then(testName => {
                        cell.text(testName);
                    });

                    // 返回空字符串,不要返回Promise
                    return '';
                }  
            }
            // 其他列配置...
        ]
    });

    const generateString = async (input) => {
        const arr = input.split(',');
        // 用Promise.all并行请求,替代循环await提升性能
        const testNamePromises = arr.map(number => 
            $.ajax({
                url: `https://localhost:7136/api/Test/${number}`,
                type: 'GET',
                contentType: "application/json; charset=utf-8",
                dataType: "json"
            }).then(res => res.data.testName)
        );
        const testNames = await Promise.all(testNamePromises);
        return testNames.join(',');
    };
});

额外优化说明

  • 两种方案都将原循环await请求改为Promise.all并行请求,大幅减少请求等待时间,提升页面加载效率。
  • 方案1的预加载方式更适合数据量较大的场景,能避免渲染阶段的异步请求阻塞和重复请求问题。

内容的提问来源于stack exchange,提问作者Bayu Pratama

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 14:50:30