从函数生成数组传入DataTable遇空表问题求助
嘿,我一眼就看出你遇到的核心问题是异步回调的执行时机不对!
问题到底出在哪?
idElement和idMoreAtr都是带回调的异步函数——也就是说,你调用它们之后,JavaScript不会等它们返回结果,而是直接往下执行初始化DataTable的代码。这时候set数组还完全是空的,表格自然显示不出东西。而你在函数内部打印set正常,是因为那时候异步请求已经跑完,数据已经被塞进数组里了。
两种靠谱的解决方案
方案1:用Promise+async/await搞定异步流程(推荐)
把你的异步函数封装成Promise,然后用Promise.all()等所有请求都完成后再初始化表格,这样就能保证表格拿到的是完整的数据:
$(window).on('load', function() { var count = 5; let set = []; // 把idElement转成返回Promise的函数 function getId(index) { return new Promise((resolve, reject) => { idElement.call(index, (error, id) => { error ? reject(error) : resolve(id); }); }); } // 把idMoreAtr也转成Promise函数 function getDetails(id) { return new Promise((resolve, reject) => { idMoreAtr(id, (error, result) => { if (error) reject(errorMsg); else resolve({ name: result[0], age: result[1].toNumber() }); }); }); } // 异步函数里统一处理所有请求 async function loadDataAndRenderTable() { const allRequests = []; for (let i = 0; i < count; i++) { // 链式调用两个异步操作,收集到promise数组里 const request = getId(i) .then(id => getDetails(id)) .then(data => set.push(data)) .catch(err => console.error('请求出错:', err)); allRequests.push(request); } // 等所有请求都完成 await Promise.all(allRequests); // 现在set里有数据了,初始化表格 $('#table').DataTable({ data: set, columns: [ { title: "Name", data: "name" }, { title: "Age", data: "age" } ] }); } // 执行整个流程 loadDataAndRenderTable(); });
方案2:先建空表格,数据齐了再塞进去
如果你不想用Promise,也可以先初始化一个空表格,然后用计数器跟踪所有异步请求的完成情况,等所有数据都收集完再更新表格:
$(window).on('load', function() { var count = 5; let set = []; let doneCount = 0; // 先初始化空表格 const table = $('#table').DataTable({ columns: [ { title: "Name" }, { title: "Age" } ] }); function addToSet(name, age) { set.push({ name, age }); doneCount++; // 所有请求都完成了,更新表格 if (doneCount === count) { table.clear().rows.add(set).draw(); } } for (let i = 0; i < count; i++) { idElement.call(i, (error, id) => { if (error) { console.error(error); doneCount++; // 出错也要算完成,不然会一直等 return; } idMoreAtr(id, (error, result) => { if (error) { console.log(errorMsg); doneCount++; return; } const name = result[0]; const age = result[1].toNumber(); addToSet(name, age); }); }); } });
小提醒
不管用哪种方案,都要记得处理错误情况——比如某个请求失败了,也要把计数器加上,不然会导致表格永远不会更新哦!
内容的提问来源于stack exchange,提问作者hamiltonianGroup
相关产品推荐
相关产品推荐

