2015-09-07 23 views
6

Jak używać $.when w JQuery z przykutymi obietnicami, aby upewnić się, że moje żądania ajaxowe zostały wykonane we właściwej kolejności?

Mam tablicę o nazwie costArray, która składa się z wielu dynamicznych obiektów. Dla każdego elementu w tej tablicy, zadzwonię do żądania Ajax o nazwie GetWorkOrder, które zwraca WorkOrder, który jest w zasadzie elementem wiersza tabeli z klasą .workOrder i dołącza go do tabeli o identyfikatorze #tbodyWorkOrders.

Po przetworzeniu wszystkich elementów w tablicy używam $.when, aby dać mi znać, kiedy mogę obliczyć SubTotal każdego z WorkOrder.

Mój problem polega na tym, że moje WorkOrder s są wstawiane do losowych zamówień, ponieważ żądania ajax są przetwarzane asynchronicznie. Jak mogę zapewnić, że moje żądania ajaxowe są przetwarzane i dołączane w poprawnej kolejności?

i = 0; 

$.each(costArray, function (key, value) { 
var d1 = $.get('/WorkOrders/GetWorkOrder', { 'i': i }, function (html) { 
    $('#tbodyWorkOrders').append(html); 
    $('.workOrder').last().find('input').val(value.Subtotal); 
}); 

$.when(d1).done(function() { 
    SetSubtotal(); 
    i++; 
}); 

Edit:

costArray pochodzi z wcześniejszego wywołania ajax i jest tablicą elementów, które ja wkładając do wierszy tabeli:

var costArray = JSON.parse([{"Trade":"Plasterer","Notes":"Test","Subtotal":"3781.00"}]); 

Linia:

$('.workOrder').last().find('input').val(value.Subtotal); 

jest jednym z wielu, który pobiera wartości z GetWorkOrder i umieszcza je we właściwych wejściach, ale Zostawiłam się dodatkowy kod dla jasności

+0

Należy uwzględnić liczbę całkowitą, która wskazuje kolejność zamknięcia odwołania powodzenia. – bhspencer

Odpowiedz

4

$.when() procesy wszystkie obietnice je przekazać równolegle, nie sekwencyjny (od asynchroniczne operacje zostały już rozpoczęte przed nawet dostać się do $.when()).

Będzie zbierać wyniki dla ciebie w kolejności przekazywania obietnic do $.when(), ale nie ma żadnej gwarancji co do kolejności wykonania operacji przekazanych do niego.

To, co sugerowałbym, to zbieranie wszystkich wyników (w kolejności), a następnie wstawianie ich w kolejności po ich zakończeniu.

Próbowałem zrestrukturyzować twój kod, ale nie jest jasne, które elementy z formularza costArray chcesz przekazać do połączenia z Ajax. W kodzie nie przekazałeś niczego od costArray, ale tekst twojego pytania mówi, że powinieneś. Tak czy inaczej, oto zarys strukturalny, jak to może działać:

var promises = costArray.map(function (value, index) { 
    // Fix: you need to pass something from costArray to your ajax call here 
    return $.get('/WorkOrders/GetWorkOrder', { 'i': value }); 
}); 
$.when.apply($, promises).done(function() { 
    // all ajax calls are done here and are in order in the results array 
    // due to the wonders of jQuery, the results of the ajax call 
    // are in arguments[0][0], arguments[1][0], arguments[2][0], etc... 
    for (var i = 0; i < arguments.length; i++) { 
     var html = arguments[i][0]; 
     $('#tbodyWorkOrders').append(html); 
    } 
    SetSubtotal(); 
}); 
+0

Proszę użyć innej frazy z "' $ .when "przetwarza operacje" – Bergi

+0

@Bergi - zmieniono. – jfriend00

+1

nie myśl "$.gdy 'bierze tablicę jako argument bez użycia' apply() ' – charlietfl

1

owinąć go w funkcji i przywołać go z ajax sukcesu:

ajax(0); 
function ajax(key) { 
    $.get('/WorkOrders/GetWorkOrder', {'i' : key }, 
     function (html) { 
      $('#tbodyWorkOrders').append(html); 
      $('.workOrder').last().find('input').val(costArray[key].Subtotal); 
      SetSubtotal(); 
      key++; 
      if (key < costArray.length) 
       ajax(key); 
     }); 
} 

EDIT: Na dalszych rozważań, natomiast jest to jeden sposób, aby to zrobić, pociąga za sobą wywołania ajax tylko jeden na raz, który nie jest bardzo efektywny czasowo. Poszedłbym z odpowiedzią jfreind00.

Powiązane problemy