2011-08-01 7 views
5

Urządzenie zdecydowanie zaleca, aby nie ustawiać async na false podczas wykonywania żądania $.ajax.Taktyka, aby uniknąć używania async: false z jQuery?

Jednak często spotykam się z problemem solutions w związku z problemami synchronizacji związanymi z robieniem tego. A potem widziałem ludzi, którzy byli chastised za niezgodne z zaleceniem doktorów.

Powiedziawszy to, próbowałem użyć promise, aby uniknąć używania async:false bez powodzenia.

Oto kod, którego używam. Mam zdarzenie onclick, który wywołuje addToOrder:

function saveTemplate() { 
    var formData = getFormData(); 
    return $.ajax({ 
     type: "POST", 
     url: "/p/session/save/" + sessionid + "/template/<?php echo $templateID ?>/", 
     data: formData, 
     async: true, 
     success: function(msg){ 
      var rsp = $.parseJSON(msg); 
      if (rsp.response === 'Saved') { 
       sessionid = rsp.sessionid; 
       $("#save-preview-data-response").html("&nbsp;&nbsp;&nbsp;" + rsp.response).fadeIn(100).delay(1000).fadeOut(1000); 
      } else { 
       $("#save-preview-data-response").css('color','#ff0000').html("&nbsp;&nbsp;&nbsp;" + rsp.response).fadeIn(100).delay(1000).fadeOut(1000); 
      } 
     } 
    }); 
} 

function addToOrder() { 
    var saved = saveTemplate(); 
    var issaved; 
    saved.success(function(e) { 
     var rsp = $.parseJSON(e); 
     issaved = (rsp.response == 'Saved') ? true : false; 
    }); 
    if(issaved) { 
     $.ajax({ 
      type: "POST", 
      url: "<?php echo $baseURL; ?>addToOrder/respond/json", 
      data: "sid=" + sessionid, 
      async: true, 
      success: function(msg){ 
       var rsp = $.parseJSON(msg); 
       if (rsp.response === 'Saved') { 
        alert(msg); 
       } 
      } 
     }); 
    } 
} 

issaved zawsze będzie oceniać na false, ponieważ jest oceniany przed saveTemplate miał czas do uruchomienia. Jedyne rozwiązanie, jakie znalazłem, to ustawić async:false, ale biorę ostrzeżenia, które widziałem poważnie i wolę nie. Jakie są inne rozwiązania?

Odpowiedz

11

Taktyka, aby uniknąć użycia async: false z jQuery?

Dowiedz się, jak kochać zwrotne. :-) Kiedy ludzie to zrobić:

// The synchronous way 
function doSomething() { 
    var foo; 
    $.ajax({ 
     url: "/the/url", 
     async: false, 
     success: function(response) { 
      foo = response.foo; 
     } 
    }); 
    return foo; 
} 

// ...somewhere else, we use it 
function flurgle() { 
    var bar = /* go get `bar` from somewhere */; 
    var x = 52; 

    if (doSomething() === bar) { 
     x -= 10; 
    } 
    niftyFunctionUsing(x); 
} 

... the, asynchroniczny sposób zdarzeniami naprawdę nie jest to, że znacznie różni:

// The asynchronous way 
function doSomething(callback) { 
    $.ajax({ 
     url: "/the/url", 
     success: function(response) { 
      callback(response.foo); 
     } 
    }); 
} 

// ...somewhere else, we use it 
function flurgle() { 
    var bar = /* go get `bar` from somewhere */; 
    var x = 52; 

    doSomething(function(foo) { 
     if (foo === bar) { 
      x -= 10; 
     } 
     niftyFunctionUsing(x); 
    }); 
} 

Od callbacks często wiążą zamknięć (Powyższe nich zrobić , to jak mamy dostępu x i bar), ten artykuł z mojego bloga mogą być pomocne: Closures are not complicated

+0

Tak, właśnie to próbowałem powiedzieć: pobiłeś mnie, pisząc kod, ale prawie się pomyliłem, nie zauważając, że twoje Zrób coś w drugim przykładzie było zaakceptowaniem callback jako funkcja; ;-) – Chris

+0

Świetne wyjaśnienie i odpowiedź. Dzięki :) – Nick

0

Połóż drugie wywołanie funkcji .ajax() wewnątrz funkcji .success() pierwszej.

+0

'saveTemplate' jest używany gdzie indziej i nie jest wyłącznie sprzężony z' addToOrder' (Np. Użytkownik w mojej aplikacji może zapisać swój postęp w dowolnym momencie, który wywołuje 'saveTemplate' - jednak gdy przesyłają" zamówienie "I zapisać ich pracę po raz ostatni, a następnie przystąpić do dodawania ich szablonu do zamówienia. – Nick

+0

Nie jest to główna .success(), a następnie jedna wewnątrz '.addToOrder()', w której również masz 'issaved = (rsp.response = = 'Saved')? True: false; '. – evan

1

można zmienić funkcję SaveTemplate przyjąć parametr, który jest funkcją, która jest prowadzona na strzał. Następnie w funkcji addToOrder możesz wygenerować anonimową funkcję z kodem, który tam masz lub refaktorem, dzięki czemu większość tego kodu znajduje się w innej funkcji, którą możesz podać po nazwie.

Pomysł polega na tym, że z asynchronicznym kodem, gdy wykonasz połączenie asynchroniczne, przestaniesz pracować nad tym problemem (tj. Kod zapisu) i zaczniesz działać w swoim oddzwanianiu. Możesz nadal robić niezwiązane ze sobą rzeczy po wywołaniu asynchronicznym (np. Wstawianie wiadomości do użytkownika "proszę czekać"), ale każdy kolejny kod związany z zapisem musi być w funkcji wywoływanej przez zestaw wywołania zwrotnego w właściwości success ajax konfiguracja.

Powiązane problemy