我不确定如何构建此列表(这是一个字符串),然后作为一个完整的字符串返回。 我已经完成了上一期的工作,但我觉得这个问题真的让我很烦恼。 buildItem()应该遍历item,然后递归地构建一个列表,同时从另一个回调中获取totalCost。我知道它是异步工作的......
+------+------+------+------------+--------+---------+----------+------------+
| Year | Code | Unit | CA | Unit_P | CA_P | Unit_PPP | CA_PPP |
+------+------+------+------------+--------+---------+----------+------------+
| 2017 | 280 | 6 | 1789027.00 | 16 | 4800000 | 8 | 2385027.00 |
| 2017 | 281 | 0 | 0.00 | 2 | 500000 | 0 | 0.00 |
| 2017 | 282 | 0 | 0.00 | 1 | 250000 | 0 | 0.00 |
+------+------+------+------------+--------+---------+----------+------------+
应该附加最终的'通过在整个文件中附加而创建的html字符串。
buildItem(data, function(html){
$('#nestable ol').append(html);
});
我知道
function buildItem(item, callback) {
getTotalCost(item, function(totalCost) {
var html = "<li class='dd-item' data-id='" + item.id + "' data-email='" + item.email + "' data-title='" + item.corporateTitle + "' data-name='" + item.firstName + " " + item.lastName + "' id='" + item.id + "'>";
if (item.children && item.children.length > 0) {
html += "<ol class='dd-list'>";
$.each(item.children, function (index, sub) {
buildItem(item, function(subHtml){
html += subHtml;
})
})
html += "</ol>";
}
html += "</li>";
callback(html);
});
}
由于javascript是异步的,所以不应该工作。我不确定如何从递归函数返回?如果我要做像
这样的事情buildItem(item, function(subHtml){
html += subHtml;
})
您将获得重复的价值,因为您已经拥有了起始价值及其子女,但既然您还要回复它,那么您将把孩子带到起始值。所以它看起来像
buildItem(item, function(subHtml){
callback(subHtml);
})
那么接近解决方案的最佳方式是什么?我正在考虑制作另一个函数,假设是一个返回html的buildChild(sub),但异步的相同问题将会出现,返回将是未定义的。我已经阅读了一些可以使用回调来处理异步值的线程,但我不确定如何使用递归来处理异步值。
getTotalCost是另一个不应该意味着很多的回调函数,我偶然删除了这行,但我只需要数据库中的totalCost。
1
a
b
c
d
e
a
b
c
d
e
答案 0 :(得分:0)
您可以使用promises和async functions简化此操作:
async function getTotalCost(item) {
const data = await Promise.resolve($.ajax({
dataType: "json",
url: "/retrieveData.do?item=" + item.email
}));
return data.reduce((acc, next) => acc + next.cost, 0);
}
async function buildItem(item) {
const totalCost = await getTotalCost(item);
let html = `<li class="dd-item" data-id="${item.id}" data-email="${item.email}" data-title="${item.corporateTitle}" data-name="${item.firstName} ${item.lastName}" id="${item.id}">`;
if (item.children && item.children.length > 0) {
html += '<ol class="dd-list">';
for (const childItem of item.children) {
html += await buildItem(childItem);
}
html += "</ol>";
}
html += "</li>";
return html;
}
很遗憾,所有浏览器都不支持异步功能,因此您必须使用Babel来转换代码。
我还添加了一些新的ES6功能:arrow functions,const
和template literals。
答案 1 :(得分:0)
如果您通过同步执行程序nsynjs执行代码,则可以将慢速ajax请求与逻辑和递归混合在一起。
步骤1.将您的逻辑编写为同步,并将其置于函数中:
function process(item) {
function getTotalCost(item) {
var data = jQueryGetJSON(nsynjsCtx, "/retrieveData.do?item=" + item.email).data;
var totalCost = 0;
for (var i = 0; i < data.length; i++) {
totalCost += parseFloat(data[i].cost);
}
return totalCost;
};
function buildItem(item) {
const totalCost = getTotalCost(item);
var html = "<li class='dd-item' data-id='" + item.id + "' data-email='" + item.email + "' data-title='" + item.corporateTitle + "' data-name='" + item.firstName + " " + item.lastName + "' id='" + item.id + "'>";
if (item.children && item.children.length > 0) {
html += '<ol class="dd-list">';
for (var i=0; i<item.children.length; i++)
html += buildItem(item.children[i]);
html += "</ol>";
}
html += "</li>";
return html;
};
return buildItem(item);
};
第2步:通过nsynjs:
运行它nsynjs.run(process,{},item,function (itemHTML) {
console.log("all done",itemHTML);
});
请在此处查看更多示例:https://github.com/amaksr/nsynjs/tree/master/examples