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

Пользовательские отложенные функции jquery

У меня есть три функции, которые я пытаюсь запустить, первые две делают некоторые асинхронные вещи, которым нужны данные для третьего пользователя. Я хочу, чтобы третья функция срабатывала только при выполнении 1 и 2. это общая структура, но конечная функция срабатывает до окончания 1 и 2.

function run() {
    var data1 = {};
    var data2 = {};

    $.when(first(), second()).done(constructData());

    function first() {
        var d = new $.Deferred();

        //do a bunch of stuff async
        data1 = {};

        d.resolve();
    }
    function second() {


        var d = new $.Deferred();

        //do a bunch of stuff async
        data2 = {};
        d.resolve();
    }
    function constructData() {
        //do stuff with data1 and data2
    }

}

Ответ заключался в немедленном вызове данных конструкции

 $.when(first(), second()).done(constructData);
4b9b3361

Ответ 1

Вы должны вернуть объект обещания. У вас также есть ошибка в этой строке:

$.when(first(), second()).done(constructData());

он должен быть

$.when(first(), second()).done(constructData); // don't call constructData immediately

Итак, все вместе это может быть:

function run() {
    var data1 = {};
    var data2 = {};

    $.when(first(), second()).done(constructData);

    function first() {
        return $.Deferred(function() { // <-- see returning Deferred object
            var self = this;

            setTimeout(function() {   // <-- example of some async operation
                data1 = {func: 'first', data: true};
                self.resolve();       // <-- call resolve method once async is done
            }, 2000);
        });
    }
    function second() {
        return $.Deferred(function() {
            var self = this;
            setTimeout(function() {
                data2 = {func: 'second', data: true};
                self.resolve();
            }, 3000);
        });
    }
    function constructData() {
        //do stuff with data1 and data2
        console.log(data1, data2);
    }
}

http://jsfiddle.net/FwXZC/

Ответ 2

Я думаю, что вы должны first() и second() вернуть обещание: return d.promise();. Из docs:

Если один аргумент передается в jQuery.when и он не является Отсроченным или обещанием, он будет рассматриваться как разрешенный Deferred, и любые прикрепленные файлы doneCallbacks будут выполнены немедленно.

Я подозреваю, что это может быть причиной того, что вызов when вызывает constructData слишком рано.

Трудно сказать из вашего кода, но убедитесь, что вы вызываете d.resolve() после завершения асинхронных операций.

Вы можете обнаружить, что более естественным подходом к явным установкам data1 и data2 является вместо этого использование данных, которые предоставляются при вызове resolve. Это означало бы, что ваш вызов when будет выглядеть примерно так:

$.when(first(), second()).done(function(result1, result2) {
    data1 = result1[0];
    data2 = result2[0];

    constructData();
});

Обратите внимание, что точный формат результатов, предоставляемых методу done, зависит от характера отложенных объектов. Если promises возвращаются из вызова $.ajax, результаты должны иметь вид [data, statusText, jqXhrObject].