带有嵌套AJAX调用的JavaScript承诺不起作用

带有嵌套AJAX调用的JavaScript承诺不起作用,javascript,ajax,asynchronous,promise,Javascript,Ajax,Asynchronous,Promise,在我的代码中,我有一个带有3个嵌套AJAX调用的函数,为了让它工作,我必须将Async=false设置为 正如我所读到的,Async=false已被弃用,我用promissions替换了Async=false 这是我编辑之前的函数: self.getOrders = function (name) { var orders= []; var order= function (item, type1, type2) { var self = this;

在我的代码中,我有一个带有3个嵌套AJAX调用的函数,为了让它工作,我必须将Async=false设置为

正如我所读到的,Async=false已被弃用,我用promissions替换了Async=false

这是我编辑之前的函数:

self.getOrders = function (name) {
    var orders= [];
    var order= function (item, type1, type2) {
        var self = this;
        self.order= item;
        self.type1= type1;
        self.type2= type2;
    }

$.ajax({
    url: "/API/orders/" + name,
    type: "GET",
    async: false,
    success: function (orderResults) {
        var mappedOrders = $.map(orderResults, function (orderItem) {
        $.ajax({
            url: "/API/orders/property/" + orderItem.id + "/type1",
            type: "GET",
            async: false,
            success: function (property1Results) {
                 $.ajax({
                     url: "/API/orders/property/" + orderItem.id + "/type2",
                     type: "GET",
                     async: false,
                     success: function (property2Results) {
                          orders.push(new order(orderItem, property1Results, property2Results));
                        }
                    });
                  }
                });
            })
        }
    });
    return orders;
这个函数工作得很好,我得到了数据端,一切都很好

然后我将函数改为使用承诺,而不是Async=false, 这是经过编辑的功能,承诺:

以及函数调用:

self.populateOrders = function (name) {
    var mappedOrders = $.map(self.service.getOrders(name), function (item) {
        return new Order(item)
        });
    self.orders(mappedOrders);
}
新函数不起作用,我从firstPromise返回一个带有反斜杠的错误json,返回的orders对象为空

知道我做错了什么吗?我花了那么多时间在这上面,但还是弄不明白


提前谢谢

chrome 2016年8月52日最近引入的一个bug可能会导致这种行为:嵌套请求的答案被忽略。 希望它不会持续太久


尝试添加缓存:false

在循环中嵌套ajax调用是一个很难管理的问题。你可以这样做

创建一个承诺,在整个过程完成时通知调用方 等待所有内部ajax调用的解析 解决你的主要承诺,通知来电者
在本例中,请注意,我使用$.when.apply等待延迟数组。

请共享函数的其余部分,必要时删除不相关的代码。您需要返回承诺而不是orders数组,并在该承诺的resolve回调中访问您的orders数组。我编辑了我的问题。在嵌套承诺中,您必须返回嵌套承诺。返回secondPromise和thirdPromise,而不是仅声明它们。此外,您必须使用then而不是done来链接承诺。您真的需要嵌套它们吗?看起来它们可以并行运行。虽然这应该可以工作,但请注意,我无法在JSFIDLE中测试这一点,因为您没有提供JSFIDLE。如果您对它有问题,请将它们封装在JSFIDLE中,我将考虑如何解决它。@Bergi的评论使我意识到您的ajax内部ajax调用不需要嵌套。这在一定程度上简化了代码,因此我进行了相应的编辑。非常感谢您的明确回答,我现在将尝试它,并会让您知道,谢谢!这几乎是一个好答案,但你应该避免!如果您只是使用Than进行链接,则无需通知任何内容。避免“完成”和“成功”回调@Ozan它正在工作,但不是完全工作,我正在获取数据,没有任何控制台错误,但是从ajax1和ajax2返回的数据很奇怪,使用ko.toJSON它看起来像:[[{地址:test,城市:test,state:NY,zip:null}],success,{readyState:4,responseText:[\r\n{\r\n\address\:\test\,\r\n\city\:\test\,\r\n\state\:\NY\,\r\n\zip\:null\r\n}\r\n}\r\n],responseJSON}]等。在页面上它看起来是这样的:[对象对象]s,u,c,c,e,s,s4,函数a{var b;if2==t{if!j{j=etc!!
self.populateOrders = function (name) {
    var mappedOrders = $.map(self.service.getOrders(name), function (item) {
        return new Order(item)
        });
    self.orders(mappedOrders);
}
self.getOrders = function (name) {
    var mainDeferred = $.Deferred();
    var orders = [];
    var order = function (item, type1, type2) {
        var self = this;
        self.order = item;
        self.type1 = type1;
        self.type2 = type2;
    }

    $.ajax({
        url: "/API/orders/" + name,
        type: "GET",
        success: function (orderResults) {
            var innerwait = [];

            var mappedOrders = $.map(orderResults, function (orderItem) {
                var ajax1 = $.ajax({
                    url: "/API/orders/property/" + orderItem.id + "/type1",
                    type: "GET"
                });
                var ajax2 = $.ajax({
                    url: "/API/orders/property/" + orderItem.id + "/type2",
                    type: "GET"
                });
                $.when(ajax1, ajax2).done(function (property1Results, property2Results) {  
                    orders.push(new order(orderItem, property1Results[0], property2Results[0])))
                });
                innerwait.push(ajax1, ajax2);
            });;

            $.when.apply(null, innerwait) //make sure to wait for all ajax requests to finish
                .done(function () {
                    mainDeferred.resolve(orders); //now that we are sure the orders array is filled, we can resolve mainDeferred with orders array
                });
        }
    });

    return mainDeferred.promise();
}


self.populateOrders = function (name) {
    self.service.getOrders(name).done(function (orders) { //use .done() method to wait for the .getOrders() to resolve
        var mappedOrders = $.map(orders, function (item) {
            return new Order(item)
        });
        self.orders(mappedOrders);
    });
}