jQuery Deferred - Добавяне на обратно извикване към Deferred договора

Опитвам се да добавя друго асинхронно извикване към договора на съществуващ Deferred, преди състоянието му да е настроено на успех. Вместо да опитате да обясните това на английски, вижте следния псевдокод:

$.when(
    $.ajax({        
        url: someUrl,
        data: data,
        async: true,        
        success: function (data, textStatus, jqXhr) {
            console.log('Call 1 done.')
            jqXhr.pipe(
                $.ajax({        
                    url: someUrl,
                    data: data,
                    async: true,        
                    success: function (data, textStatus, jqXhr) {
                        console.log('Call 2 done.');
                    },       
                })
            );
        },       
    }),
    $.ajax({        
        url: someUrl,
        data: data,
        async: true,        
        success: function (data, textStatus, jqXhr) {
            console.log('Call 3 done.');
        },       
    })
).then(function(){ console.log('All done!'); });

По принцип Повикване 2 зависи от резултатите от Повикване 1. Искам Повикване 1 и Повикване 3 да се изпълняват паралелно. След като всичките 3 обаждания са завършени, искам да се изпълни кодът All Done. Моето разбиране е, че Deferred.pipe() трябва да свърже друго асинхронно повикване към даденото отложено, но на практика винаги получавам Повикване 2 завършващо след Всичко готово.

Някой знае ли как да накарам jQuery's Deferred да прави това, което искам? Надяваме се, че решението не включва допълнително разкъсване на кода на части.

Благодаря за всяка помощ.

АКТУАЛИЗАЦИЯ: Моля, вижте моя последващ въпрос .


person MgSam    schedule 28.09.2012    source източник


Отговори (1)


Трябва да извикате .pipe на отложения обект, върнат от първото извикване $.ajax, а не вътре в обратното извикване за успех (това няма никакъв ефект):

$.when(
    $.ajax({        
        // ...      
    }).pipe(function() {
        // return a deferred object from .pipe
        return $.ajax({        
            // ...      
        });
    }),
    $.ajax({        
        // ...       
    })
).done(function(){ console.log('All done!'); });

.pipe връща нов отложен обект, който се разрешава само след като и оригиналният отложен обект, и върнатият обект бъдат разрешени.

person Felix Kling    schedule 28.09.2012
comment
прави го в 1.8+, където .then вече е еквивалентен на самия .pipe - person Alnitak; 28.09.2012
comment
О, добре, спомням си нещо такова... наистина трябва да актуализират документите. Предполагам, че в този случай няма голяма разлика, но има повече смисъл. Благодаря! - person Felix Kling; 28.09.2012
comment
ISTR разликата е, че .pipe връща ново обещание, докато .then връща първоначалното обещание. - person Alnitak; 28.09.2012
comment
Добре, това работи. Има ли начин да се предадат резултатите от Call 1 във функцията Call 2, без да се използват затваряния или глобални променливи? - person MgSam; 28.09.2012
comment
@MgSam: Разбира се, резултатът се предава като аргументи на обратното извикване .pipe. Не съм сигурен кои стойности се предават за отговорите на Ajax, така че просто запишете аргументите и вижте какво ви трябва. - person Felix Kling; 28.09.2012
comment
Добре. Ситуацията ми всъщност е по-сложна, отколкото показа първоначалното ми обяснение. Моля, вижте актуализирания въпрос. - person MgSam; 28.09.2012