Mam widget JavaScript, który zapewnia standardowe punkty rozszerzenia. Jednym z nich jest beforecreate
funkcja. Powinien powrócić, false
aby zapobiec tworzeniu elementu.
Dodałem wywołanie Ajax do tej funkcji za pomocą jQuery:
beforecreate: function (node, targetNode, type, to) {
jQuery.get('http://example.com/catalog/create/' + targetNode.id + '?name=' + encode(to.inp[0].value),
function (result) {
if (result.isOk == false)
alert(result.message);
});
}
Chcę jednak zapobiec tworzeniu elementu przez mój widget, więc powinienem powrócić false
w funkcji macierzystej, a nie w wywołaniu zwrotnym. Czy istnieje sposób wykonania synchronicznego żądania AJAX przy użyciu jQuery lub innego interfejsu API przeglądarki?
javascript
jquery
ajax
asynchronous
Artem Tichomirow
źródło
źródło
beforecreate
.Odpowiedzi:
Z dokumentacji jQuery : określasz opcję asynchroniczną na false, aby uzyskać synchroniczne żądanie Ajax. Następnie oddzwonienie może ustawić niektóre dane przed kontynuowaniem funkcji matki.
Oto jak wyglądałby Twój kod, gdyby został zmieniony zgodnie z sugestią:
źródło
async: false
jest nadal obsługiwany w jQuery> = 1.8. Zdolność do używaniaasync: false
z jqXHR ($.Deferred
) jest przestarzała. Innymi słowy, należy zastosować nowsze opcje powodzenia / błędu / pełnego wywołania zwrotnego zamiast starszych metod, npjqXHR.done()
.Możesz przełączyć konfigurację Ajax jQuery w tryb synchroniczny, dzwoniąc
A następnie wykonuj połączenia Ajax za pomocą
jQuery.get( ... );
Następnie po prostu włącz go ponownie
Myślę, że działa to tak samo, jak sugeruje @Adam, ale może być pomocne dla kogoś, kto chce zmienić konfigurację swojej
jQuery.get()
lubjQuery.post()
bardziej złożonejjQuery.ajax()
składni.źródło
$.ajax()
”. ;)Doskonałe rozwiązanie! Zauważyłem, gdy próbowałem go zaimplementować, że jeśli zwróciłem wartość w klauzuli sukcesu, to wróciła jako niezdefiniowana. Musiałem zapisać go w zmiennej i zwrócić tę zmienną. Oto metoda, którą wymyśliłem:
źródło
getWhatever
. W ten sposób nic nie zwróciłeś, tj.undefined
Od swojegogetWhatever
.We wszystkich tych odpowiedziach nie ma sensu, aby wykonanie wywołania Ajax za pomocą async: false spowodowało zawieszenie się przeglądarki do momentu zakończenia żądania Ajax. Korzystanie z biblioteki kontroli przepływu rozwiąże ten problem bez zawieszania przeglądarki. Oto przykład z Frame.js :
źródło
źródło
getURL
vsget
? Dlaczego zawiesi się moja przeglądarka?” itp.Uwaga: Nie należy używać z
async: false
powodu tych komunikatów ostrzegawczych:Chrome ostrzega nawet o tym w konsoli:
Może to spowodować uszkodzenie strony, jeśli robisz coś takiego, ponieważ może przestać działać każdego dnia.
Jeśli chcesz to zrobić w sposób, który nadal wydaje się być synchroniczny, ale nadal nie blokuje, powinieneś użyć async / await i prawdopodobnie również jakiegoś ajax, który jest oparty na obietnicach, takich jak nowy interfejs API Fetch
Edycja chrome pracuje nad Niedozwoleniem synchronizacji XHR podczas zamykania strony, gdy strona jest nawigowana lub zamykana przez użytkownika. Obejmuje to przed załadowaniem, rozładowaniem, ukryciem strony i zmianą widoczności.
jeśli jest to przypadek użycia to może chcesz przyjrzeć się navigator.sendBeacon zamiast
Strona może również wyłączyć żądanie synchronizacji z nagłówkami HTTP lub atrybutem iframe
źródło
await fetch(url)
połączenie wtry... catch
blok, aby wychwycić wszelkie błędy asynchroniczne.async
na początku, więc możesz po prostu gofoo().catch(...)
złapaćbeforeunload
ale potem cofnął zmianę po negatywnej opinii bugs.chromium.org/p/chromium/issues/detail?id=952452Pamiętaj, że jeśli wykonujesz wywołanie Ajax między domenami (używając JSONP ) - nie możesz tego zrobić synchronicznie,
async
flaga zostanie zignorowana przez jQuery.Do połączeń JSONP możesz użyć:
źródło
Z
async: false
ciebie dostać się zablokowany przeglądarkę. W przypadku nieblokującego rozwiązania synchronicznego można użyć:ES6 / ECMAScript2015
Z ES6 możesz korzystać z generatora i biblioteki co :
ES7
Z ES7 możesz po prostu użyć asyc czekać:
źródło
async function
do wcześniejszego utworzeniabeforecreate: async function(....
i usunąć samodzielnie wywoływaną funkcję asynchronicznąUżyłem odpowiedzi udzielonej przez Carcione i zmodyfikowałem ją, aby używała JSON.
Dodałem typ danych „JSON” i zmieniłem tekst .responseText na responseJSON .
Pobrałem również status za pomocą właściwości statusText zwróconego obiektu. Zauważ, że jest to stan odpowiedzi Ajax, a nie to, czy JSON jest poprawny.
Back-end musi zwrócić odpowiedź w poprawnym (poprawnie uformowanym) JSON, w przeciwnym razie zwracany obiekt nie zostanie zdefiniowany.
Przy udzielaniu odpowiedzi na oryginalne pytanie należy wziąć pod uwagę dwa aspekty. Jeden mówi Ajaxowi, aby działał synchronicznie (ustawiając async: false ), a drugi zwraca odpowiedź za pomocą instrukcji return funkcji wywołującej, a nie w funkcji wywołania zwrotnego.
Próbowałem też z POST i zadziałało.
Zmieniłem GET na POST i dodałem dane: postdata
Zauważ, że powyższy kod działa tylko w przypadku, gdy asynchronizacja jest fałszywa . Jeśli miałbyś ustawić async: true, zwrócony obiekt jqxhr nie byłby prawidłowy w momencie powrotu wywołania AJAX, tylko później, gdy zakończy się wywołanie asynchroniczne, ale jest o wiele za późno, aby ustawić zmienną odpowiedzi .
źródło
To jest przykład:
źródło
async false
z rozwiązania opartego na obietnicach. To tylko blokuje przeglądarkę bez żadnych korzyści.ajax
wywołania już zwracają) i.then()
lubdone()
(jak już pokazuje). Blokowanie przeglądarki jest bardzo słabym doświadczeniem użytkownika. Jak powiedziałem, posiadanieasync: false
w tym przykładzie jest całkowitą stratą czasu.Po pierwsze powinniśmy zrozumieć, kiedy używamy $ .ajax i kiedy używamy $ .get / $. Post
Kiedy wymagamy niskiego poziomu kontroli nad żądaniem ajax, takim jak ustawienia nagłówka żądania, ustawienia buforowania, ustawienia synchroniczne itp., Powinniśmy wybrać $ .ajax.
$ .get / $. post: Gdy nie wymagamy kontroli niskiego poziomu nad żądaniem ajax. Wystarczy pobrać / wysłać dane na serwer. To jest skrót
i dlatego nie możemy używać innych funkcji (synchronizacja, pamięć podręczna itp.) z postem $ .get / $.
Stąd dla kontroli niskiego poziomu (synchronizacji, pamięci podręcznej itp.) Nad żądaniem ajax, powinniśmy wybrać $ .ajax
źródło
to moja prosta implementacja dla żądań ASYNC z jQuery. Mam nadzieję, że pomoże to każdemu.
źródło
Ponieważ
XMLHttpReponse
działanie synchroniczne jest przestarzałe, wymyśliłem następujące rozwiązanie, które się zawijaXMLHttpRequest
. Pozwala to na uporządkowanie zapytań AJAX, a jednocześnie jest asynchroniczne z natury, co jest bardzo przydatne w przypadku tokenów CSRF do jednorazowego użytku.Jest również przezroczysty, więc biblioteki takie jak jQuery będą działać płynnie.
źródło
Ponieważ pierwotne pytanie dotyczyło
jQuery.get
, warto tutaj wspomnieć, że (jak wspomniano tutaj ) można użyćasync: false
w,$.get()
ale najlepiej go unikać , ponieważ asynchronicznyXMLHTTPRequest
jest przestarzały (a przeglądarka może ostrzec):źródło
Ustaw
asyn:false
w żądaniu ajax, aby było synchroniczne.Oto przykładowy kod:
Może to spowodować brak reakcji ekranu.
źródło