async/await未等待DataTable AJAX加载完成即输出空表格问题排查
前端异步时序问题排查与修复方案
问题根因
async/await的生效前提,是当前等待的Promise真的绑定到了所有异步执行流程上,你现在的代码完全不满足这个前提:
- DataTable初始化过程中配置的
ajax请求,是插件内部独立发起的异步逻辑,没有和外层getTableBody的执行流做关联 - 现有代码的实际执行顺序:
- 调用DataTable初始化方法,方法会立刻返回表格实例,同时在后台静默发起AJAX数据请求
- 初始化方法返回后,代码不会等待AJAX结果,立刻往下读取当前还是空的表格DOM内容
- 读完空DOM后立刻销毁表格,把空的DOM内容作为函数返回值
- 这个返回时机远早于AJAX拉取数据、渲染到DOM的时机,所以
await拿到的永远是空表格,根本触发不了等待效果。
修复方式
需要手动把「DataTable AJAX数据加载完成、DOM渲染完毕」的节点,和Promise的resolve方法绑定,让整个流程真正变成可被await等待的异步任务,修改完成后你原来写的exportPdf逻辑不需要做任何调整,await会正常等待数据加载完成:
const getTableBody = async (crop) => { // 用Promise包裹完整的异步加载流程 return new Promise((resolve) => { const table = $('#pests_js_table').DataTable({ pageLength: 50, processing: true, ajax: { url: '/assets/ajax/table_ajax_handler.php', type: 'POST', data: { action: "getPestsForTable" }, // 关键钩子:等AJAX数据解析完成、准备渲染DOM时触发 dataSrc: function(res) { // 数据准备就绪后,读取表格DOM内容 const tableContent = $('#pests_js_table').html(); // 读取完成后销毁表格实例 table.destroy(); // 触发Promise完成,把内容返回给await等待逻辑 resolve(tableContent); return res.data; // 必须返回原始数据,保证DataTable正常渲染 } }, columns: [ { "data": "crop" }, { "data": "pests" }, { "data": "chemical" }, { "data": "product" }, { "data": "rate" }, { "data": "max_no" }, { "data": "hi" }, { "data": "mrl" }, { "data": "pcs_no" }, { "data": "supplier" }, { "data": "use_by_date" } ], columnDefs: [ { "targets": [0], "visible": false, "searchable": true }, { "targets": [1], "visible": true, "searchable": true } ], order: [[2, "asc"]], // 删掉原代码中重复的空rowsGroup配置 rowsGroup: [1, 2, 4, 5, 6, 7, 9] }); }); }
注意事项
- 不要在DataTable初始化完成后立刻读取DOM,这个节点下AJAX请求还在后台执行,DOM没有任何数据
- 不要用固定延时(比如
setTimeout)等待加载,这种方式受网络波动影响,可靠性极差 - 原代码中重复配置了两次
rowsGroup,第一次是空数组、第二次填了实际配置,记得删掉冗余的空配置
内容的提问来源于stack exchange,提问作者BranOIE
相关产品推荐
相关产品推荐

