在jQuery DataTables列定义的render函数中无法返回Promise值
jQuery DataTables异步渲染问题:从Promise返回值到表格
问题描述
在jQuery DataTables的columnDefs.render函数中调用异步Promise函数时,控制台能正常获取数据,但return语句无法将数据渲染到表格上,还会触发DataTables警告(提示无返回值)。但直接返回固定字符串(比如'nothing')就完全正常,请问如何正确从Promise中获取值并渲染到表格?
问题代码片段
{ "targets": [5], "className": 'text-center', "render": function (data, type, row, meta) { // 避免函数被多次调用 if (type === 'display') { if (typeof getJSON == 'function') { getJSON(row.ID).then(function (val) { if (val) { // 控制台能打印出正确值 console.log(JSON.stringify(val)) // 但这里的return不会被render函数捕获 return JSON.stringify(val); } else { return 'not available' } }); } } } },
无错误的代码片段(返回固定值)
{ "targets": [5], "className": 'text-center', "render": function (data, type, row, meta) { return 'nothing' } },
Promise函数
async function getJSON(deviceID) { return new Promise((resolve, reject) => { var data = JSON.stringify({ 'deviceID': deviceID }); $.ajax({ type: "POST", url: MYURL, contentType: "application/json; charset=utf-8", data: data, dataType: "json", success: function (results) { resolve(results.data) }, error: function (error) { reject(error) }, }) }) }
能避免警告但无数据渲染的代码片段
{ "targets": [5], "className": 'text-center', "render": function (data, type, row, meta) { // 声明变量避免警告 let returnValue = ''; if (type === 'display') { if (typeof getJSON == 'function') { getJSON(row.ID).then(function (val) { if (val) { returnValue = (JSON.stringify(val)) console.log(returnValue) } else { returnValue = 'not available' } }); } } return returnValue; } },
解决方案
核心原因
DataTables的render函数是同步执行的,它不会等待异步Promise完成就会返回结果。你之前的写法里,then回调中的return根本不会被render函数捕获;而提前返回空字符串只是规避了警告,但异步请求完成后修改变量也无法触发表格重新渲染。
正确实现方式
- 先返回占位内容(比如
'加载中...'),避免DataTables警告; - 异步请求完成后,直接通过DataTables提供的API定位到目标单元格,更新DOM内容。
修改后的完整代码
1. 渲染函数修改
{ "targets": [5], "className": 'text-center', "render": function (data, type, row, meta) { if (type === 'display') { if (typeof getJSON == 'function') { // 发起异步请求,完成后更新单元格 getJSON(row.ID).then(function (val) { // 处理返回值 let content = val ? JSON.stringify(val) : 'not available'; // 通过meta参数获取当前单元格的DOM节点,直接更新内容 $(table.cell(meta.row, meta.col).node()).html(content); }).catch(function() { // 处理请求失败的情况 $(table.cell(meta.row, meta.col).node()).html('请求失败'); }); } // 返回占位符,避免DataTables警告 return '加载中...'; } // 非display场景(如排序、搜索)返回原始数据,不影响表格功能 return data; } },
注意:这里的
table是你的DataTables实例对象,需要确保它在render函数的作用域内可访问。
2. 简化Promise函数
$.ajax本身就返回Promise,无需手动封装,可简化如下:
function getJSON(deviceID) { var data = JSON.stringify({ 'deviceID': deviceID }); return $.ajax({ type: "POST", url: MYURL, contentType: "application/json; charset=utf-8", data: data, dataType: "json" }).then(function(results) { return results.data; }); }
内容的提问来源于stack exchange,提问作者Shane
相关产品推荐
相关产品推荐

