2015-12-28 3 views
2

Предположим, что я смог получить ($.ajax), процесс (process_*) и сохранение (store_* =) данные A и B независимо друг от друга, и уже есть API:Дизайн API: Как я могу объединить результат двух отложенных объектов jQuery?

var store_A; 
function A() { 
    $.ajax({url: "/getA"}).done(function(data) { 
    store_A = process_A(data); 
}); } 

var store_B; 
function B() { 
    $.ajax({url: "/getB"}).done(function(data) { 
    store_B = process_B(data); 
}); } 

У меня есть функция C(), которая способна объединить store_A и store_B в что-то:

var store_C; 
function C() { 
    store_C = process_C(store_A, store_B); 
} 

Пусть A(), B() и C() является открытым API и Другим материалом является внутренность и действительно сложный код (так, например, я не могу напрямую связать $.ajax).

Я хочу, чтобы реорганизовать выше кода к новым API с помощью jQuery Deferred API, так что я могу запросить любой случай:

case1: after(A).do(C) 
case1: after(B).do(C) 
case2: afterParallelJobsFinished(A, B).do(C) 

и быть уверенным, что store_A или store_B обновляется в соответствии с просьбой и store_C обновления только после обновления одного или обоих от A/B, как требовалось.


Imaging, что у нас есть webapp, где пользователь управляет множеством доходов и расходов.

На странице загрузки мы получаем доходы и расходы от различных источников данных (то есть $.ajax) параллельно, делают вид и сохранять данные (обычно это перемешаны process_*/store_* =) и показать total = SUM(incomes) - SUM(expenses)когда все данные пришли ,

То, что case2.

Когда пользователь редактирует расходы и запрашивает частичное обновление страницы, мы находимся в case1, потому что нам нужно только загрузить/отобразить/сохранить пространства, чтобы получить правильный total = SUM(incomes) - SUM(expenses).

+0

Вы можете использовать $ .when, но вам нужно сохранить обещание в store_X. – jcubic

+0

Из двух независимых '$ .ajax()' я получаю два обещания. Как я могу объединить их? Я хочу сохранить возможность запускать 'A()' или 'B()' или 'C()' независимо. – gavenkoa

ответ

3

$.when() может принимать произвольное количество отложенных объектов. It can even take a dynamic number, если вы не знаете, сколько звонков вы сделаете.

$.when(callA(), callB()).done(function() { 
// Do stuff here when both calls are done 
}); 

function callA() { 
    return $.ajax({ 
    url: ..., 
    success: function() { 
     // Do stuff here when callA is done 
    } 
    }); 
} 

function callB() { 
    return $.ajax({ 
    url: ..., 
    success: function() { 
     // Do stuff here when callB is done 
    } 
    }); 
} 
+0

Ницца! Могу ли я использовать 'return $ .ajax(). Done (...)' синтаксис вместо 'return $ .ajax ({success: ...})'? Они эквивалентны? – gavenkoa

+1

Нет, не то же самое. Вы не хотите, чтобы 'done' был вызван, когда один из них закончен - только когда все закончится. –

+0

Спасибо. Я думаю, что мой вопрос в основном возник из-за недоразумения 'done' vs' success'. – gavenkoa

0

Теперь, когда я стал знаком с jQuery.Deffered API я хочу добавить еще несколько самостоятельно выразили примеры:

function callA() { 
    return $.ajax({ url: ... }) 
    .done(function(data) { successA(data); }) 
    .fail(function(data) { failA(data); }); 
} 

function callB() { 
    var promise1 = $.ajax({ url: ... }) 
    .done(function(data) { succB_1(data); }) 
    .fail(function(data) { failB_1(data); }); 
    var promise2 = $.ajax({ url: ... }) 
    .done(function(data) { succB_2(data); }) 
    .fail(function(data) { failB_2(data); }); 
    return $.when(promise1, promise2) 
    .done(function(data1, data2) { succCombined(data1, data2); }) 
    .fail(function(data1, data2) { failCombined(data1, data2); }); 
} 

$.when(callA(), callB()).done(function() { 
// Do stuff here when both calls are done 
}); 

Обратите внимание, что внутри callA/callB я использую data/data1/data2, потому что я знаю, внутренний API соглашение. В последних строках я не ожидаю, что callA/callB вернет что-то разумное. Но если добавить публичный API для callA/callB можно использовать:

$.when(callA(), callB()).done(function(resultA, resultB) { 
// Do stuff here when both calls are done 
}); 
2

Это пересмотр ответ Мэтью Хербста наклеивания исключительно Обещай логики. Это позволяет избежать излишней путаницы при смешивании логики Promise и обратного вызова ajax success:.

$.when(callA(), callB()).done(function() { 
    // Do stuff here when both .then()'s are complete 
}); 

function callA() { 
    return $.ajax({ 
     url: ..., 
    }).then(function(result){ 
     // Do something when callA finishes 
     return result; 
    }); 
} 

function callB() { 
    return $.ajax({ 
     url: ..., 
    }).then(function(result){ 
     // Do something when callB finishes 
     return result; 
    }); 
} 

 Смежные вопросы

  • Нет связанных вопросов^_^