所以我有这样的代码
var addExpenses = function(parent) {
return function(data) {
if (data) {
for (var i = 0; i < data.length; i++) {
var expenditure = data[i].RestrictedExpenditure;
expenditure = parseFloat(expenditure);
var child = {level: 4, name: data[i].Name, size: expenditure, children: []};
parent.children.push(child);
}
}
}
}
var addSubActivities = function(parent) {
return function(data) {
if (data) {
for (var i = 0; i < data.length; i++) {
var expenditure = data[i].Expenditure;
expenditure = parseFloat(expenditure);
if (expenditure < 0) {
expenditure = -expenditure;
}
var child = {level: 3, name: data[i].Name, size: expenditure, children: []};
parent.children.push(child);
subActivitiesDfds.push($.getJSON("http://localhost:8080/district/1/subActivities/" + data[i].Code + "/expenses", addExpenses(child)));
// subActivitiesDfds.push(dfd);
}
}
}
}
for (var i = 0; i < data.length; i++) {
var expenditure = data[i].Expenditure;
expenditure = parseFloat(expenditure);
total += expenditure;
var child = {level: 2, name: data[i].Name, size: expenditure, children: []};
root.children.push(child);
subActivitiesDfds.push($.getJSON("http://localhost:8080/district/1/activities/" + data[i].Code + "/subActivities", addSubActivities(child)));
// subActivitiesDfds.push(dfd);
}
root.size = total;
$.when.apply($, subActivitiesDfds).done(function() {
var nodes = partition.nodes(root); //渲染
我在这一行收到错误 -
parent.children.push(child);
- children 未定义。这是因为 partition.nodes(root) 破坏了父属性,这是因为在调用 addExpenses 回调之前解析了 promise 列表。
为什么?
最佳答案
问题的发生是因为在执行 $.when.apply($, subActivitiesDfds)
时,subActivitiesDfds
仅填充了顶级 promise 。为下一级生成 promise 的代码仅在顶级 promise 实现时运行。
要修复,您需要:
- 确保
addSubActivities()
在所有处理完成后返回 promise 。 - 在两个地方用
$.getJSON(..., fn)
替换$.getJSON(..., ).then(fn)
。<
您还会发现 array.map()
可以方便地构建 promise 数组。
尝试:
var addExpenses = function(parent) {
return function(data) {
if (data) {
for (var i = 0; i < data.length; i++) {
var child = {
level: 4,
name: data[i].Name,
size: parseFloat(data[i].RestrictedExpenditure),
children: []
};
parent.children.push(child);
}
}
}
}
var addSubActivities = function(parent) {
return function(data) {
if (data) {
var promises = data.map(function(item) {
var child = {
level: 3,
name: item.Name,
size: Math.abs(parseFloat(item.Expenditure)),
children: []
};
parent.children.push(child);
return $.getJSON("http://localhost:8080/district/1/subActivities/" + item.Code + "/expenses")
.then(addExpenses(child));
});
return $.when.apply($, promises);
} else {
return $.when();//resolved promise
}
}
}
var promises = data.map(function(item) {
var child = {
level: 2,
name: item.Name,
size: parseFloat(item.Expenditure),
children: []
};
root.children.push(child);
total += child.size;
return $.getJSON("http://localhost:8080/district/1/activities/" + item.Code + "/subActivities").then(addSubActivities(child));
});
root.size = total;
$.when.apply($, promises).then(function() {
var nodes = partition.nodes(root); //render
});
顶级 promises
数组仍然只填充顶级 promise ,但现在链式 .then()
确保每个 promise 只会结算当所有同步和异步子事件完成时。
关于javascript - 为什么在运行成功回调之前解决 promise ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31689320/