javascript - 为什么在运行成功回调之前解决 promise ?

标签 javascript jquery promise jquery-deferred

所以我有这样的代码

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/

相关文章:

javascript - 如何在 React 中动态更改按钮大小和颜色

javascript - "Failed to load resource: the server responded with a status of 500 (Internal Server Error)"

javascript - 在 asp.net webforms 中引用 javascript 文件

javascript - 捕获拒绝的 promise 并将其通过错误代码解决后有任何问题吗?

javascript - 正确使用 Promise.resolve

javascript - 我无法让我的 html 编码幻灯片正常工作

javascript - 将元素中的 CSS 与页面的其余部分隔离

javascript - 即使在任何新的 div 附加到其父级之后,仍将 div 保留为其父级的最后一个子级

javascript - 使用 Jquery 查看和隐藏图像

promise - 向 Bluebird promise 添加方法