Подтвердить что ты не робот

JQuery отложенный объект с вложенными вызовами ajax

У меня есть ситуация, когда мои вызовы ajax должны выполняться в определенном порядке. Я использовал объекты JQuery Deferred в других ситуациях, но не могу найти способ сделать так, чтобы это было правильно.

У меня есть функция, которая выполняет в течение жизни несколько запросов ajax. Некоторые из запросов будут выполняться во время обратного вызова других запросов.

Мой вопрос: есть способ вернуть все вложенные отложенные объекты в исходный вызов $.when?

Упрощенный пример:

function nestedAjax() {
    $.get("/", function(){
        console.log("First ajax done.");
        $.get("/", function(){
            console.log("Second ajax done.");
        });
    });
};

Я пытаюсь использовать nestedAjax функцию $.when() и $.done() следующим образом:

$.when(nestedAjax()).done(function(){
    console.log("Complete");
});​

С выходом на консоль:

> First ajax done.
> Second ajax done.
> Complete.

Я могу вернуть первый get, чтобы достичь этого:

> First ajax done.
> Complete.
> Second ajax done.

Но, очевидно, это не то, что мне нужно. Любая помощь будет оценена.

4b9b3361

Ответ 1

На самом деле это довольно просто. Хотя все вызовы AJAX являются объектами с отсрочкой, я все еще использую один для самого метода.

function nestedAjax() {
    var dfd = $.Deferred();
    $.get("/echo/json/", function(){
        console.log("First ajax done.");
        $.get("/echo/json/", function(){
             console.log("Second ajax done.");
            dfd.resolve();
        });
    });

    return dfd.promise();
};

Ответ 2

На самом деле вам не нужен дополнительный отложенный объект. Вы можете сделать то, что хотите, цепочки с помощью then():

function nestedAjax() {
    return $.get("/echo/json/").then(function(result1){
        console.log("First ajax done.");
        if (result1) {
            return result1;
        } else {
            return $.get("/echo/json/").then(function(nestedResult){
                console.log("Second ajax done.");
                return nestedResult;
            });
        }
    });
};

Я добавил некоторую логику, так как я думаю, что, вероятно, причина, по которой вы выполняете это синхронно. После этого вы можете использовать результат в $.when следующим образом:

$.when(nestedAjax(), $.get("/something/else")).then(function(nested, other) {
    console.log("Complete.", nested, other);
});

Ответ 3

Не могу добавить комментарий по какой-либо причине к вышеуказанному ответу.

Итак, я добавляю свой комментарий здесь. Вышеприведенный ответ будет работать, только если вызовы ajax бывают быстрыми и возвращаются до возврата dfd.promise().

У меня та же проблема. И как вы можете видеть. Возвращенный отложенный объект указывает, что он "ожидает": http://jsfiddle.net/BtEKa/