Mam mały problem z funkcją jquery $ .ajax ().
Mam formularz, w którym każde kliknięcie przycisku opcji lub wybór z menu rozwijanego tworzy zmienną sesji z wybraną wartością.
Teraz - mam jedno z menu rozwijanych, które ma 4 opcje - pierwsza z nich (z etykietą Brak) ma wartość = "", pozostałe mają swoje identyfikatory.
To, co chcę, to opcja Brak (z pustą wartością), aby usunąć sesję i inna, aby ją utworzyć, ale tylko wtedy, gdy sesja o tej konkretnej nazwie wyboru jeszcze nie istnieje - ponieważ wszystkie inne opcje mają przypisaną tę samą ilość - wskazuje tylko, który z nich został wybrany.
Nie jestem pewien, czy to ma sens - ale spójrz na kod - być może to wyjaśni to:
$("#add_ons select").change(function() {
// get current price of the addons
var order_price_addon = $(".order_price_addon").text();
// get price of the clicked radio button from the rel attribute
var add = $(this).children('option').attr('label');
var name = $(this).attr('name');
var val = $(this).val();
if(val == "") {
var price = parseInt(order_price_addon) - parseInt(add);
removeSession(name);
} else {
if(isSession(name) == 0) {
var price = parseInt(order_price_addon) + parseInt(add);
}
setSession(name, val);
}
$(".order_price_addon").html(price);
setSession('order_price_addon', price);
updateTotal();
});
a więc - przede wszystkim, gdy menu #add_ons select wywołuje „zmianę”, otrzymujemy do obliczeń pewne wartości z kilku elementów.
otrzymujemy atrybut label opcji z naszego select, który przechowuje wartość, która ma zostać dodana do sumy, nazwę selekcji do utworzenia sesji o tej nazwie i wartość, aby później sprawdzić, która z nich została wybrana.
teraz - sprawdzamy czy val == "" (co wskazywałoby, że wybrano opcję None) i odejmujemy kwotę od sumy jak również usuwamy sesję z nazwą selekcji.
Po tym zaczyna się problem - instrukcja else.
W przeciwnym razie - chcemy sprawdzić, czy funkcja isSession () o nazwie naszego selektora zwraca 0 czy 1 - jeśli zwraca 0 to dodajemy do sumy wartość przechowywaną w atrybucie label, ale jeśli zwraca 1 - to by sugerowało ta sesja już istnieje - wtedy zmienimy wartość tej sesji tylko poprzez jej odtworzenie - ale kwota nie zostanie do niej dodana.
Teraz funkcja isSession wygląda następująco:
function isSession(selector) {
$.ajax({
type: "POST",
url: '/order.html',
data: ({ issession : 1, selector: selector }),
dataType: "html",
success: function(data) {
return data;
},
error: function() {
alert('Error occured');
}
});
}
Teraz - problem polega na tym, że nie wiem, czy użycie "return" zwróci wynik funkcji - bo wydaje się, że nie działa - jeśli jednak wstawię sekcję "data" w success: do alert - wydaje się zwracać właściwą wartość.
Czy ktoś wie, jak zwrócić wartość z funkcji, a następnie porównać ją w następnej instrukcji?
Dzięki chłopaki - wypróbowałem to w następujący sposób:
function isSession(selector) {
$.ajax({
type: "POST",
url: '/order.html',
data: ({ issession : 1, selector: selector }),
dataType: "html",
success: function(data) {
updateResult(data);
},
error: function() {
alert('Error occured');
}
});
}
następnie funkcja updateResult ():
funkcja updateResult (dane) {wynik = dane; }
wynik - to zmienna globalna - którą następnie próbuję odczytać:
$("#add_ons select").change(function() {
// get current price of the addons
var order_price_addon = $(".order_price_addon").text();
// get price of the clicked radio button from the rel attribute
var add = $(this).children('option').attr('label');
var name = $(this).attr('name');
var val = $(this).val();
if(val == "") {
var price = parseInt(order_price_addon) - parseInt(add);
removeSession(name);
} else {
isSession(name);
if(result == 0) {
var price = parseInt(order_price_addon) + parseInt(add);
}
setSession(name, val);
}
$(".order_price_addon").html(price);
setSession('order_price_addon', price);
updateTotal();
});
ale z jakiegoś powodu - nie działa - jakiś pomysł?
Odpowiedzi:
Problem polega na tym, że nie można zwrócić wartości z wywołania asynchronicznego, takiego jak żądanie AJAX, i oczekiwać, że zadziała.
Powodem jest to, że kod oczekujący na odpowiedź został już wykonany przed odebraniem odpowiedzi.
Rozwiązaniem tego problemu jest uruchomienie niezbędnych kod wewnątrz tej
success:
zwrotnego. W ten sposób uzyskuje dostępdata
tylko wtedy, gdy jest dostępny.function isSession(selector) { $.ajax({ type: "POST", url: '/order.html', data: ({ issession : 1, selector: selector }), dataType: "html", success: function(data) { // Run the code here that needs // to access the data returned return data; }, error: function() { alert('Error occured'); } }); }
Inną możliwością (która jest właściwie tym samym) jest wywołanie funkcji wewnątrz twojego
success:
wywołania zwrotnego, która przekazuje dane, gdy są one dostępne.function isSession(selector) { $.ajax({ type: "POST", url: '/order.html', data: ({ issession : 1, selector: selector }), dataType: "html", success: function(data) { // Call this function on success someFunction( data ); return data; }, error: function() { alert('Error occured'); } }); } function someFunction( data ) { // Do something with your data }
źródło
async: false
). W niektórych przypadkach posiadanie wywołania asynchronicznego nie jest wymagane. Więcej na temat jquery.ajax () doc api.jquery.com/jQuery.ajax , nie toAs of jQuery 1.8, the use of async: false with jqXHR ($.Deferred) is deprecated;
Istnieje wiele sposobów uzyskania odpowiedzi jQuery AJAX. Dzielę się z wami dwoma typowymi podejściami:
Pierwszy:
/** * jQuery ajax method with async = false, to return response * @param {mix} selector - your selector * @return {mix} - your ajax response/error */ function isSession(selector) { return $.ajax({ type: "POST", url: '/order.html', data: { issession: 1, selector: selector }, dataType: "html", async: !1, error: function() { alert("Error occured") } }); } // global param var selector = !0; // get return ajax object var ajaxObj = isSession(selector); // store ajax response in var var ajaxResponse = ajaxObj.responseText; // check ajax response console.log(ajaxResponse); // your ajax callback function for success ajaxObj.success(function(response) { alert(response); });
Druga:
/** * xResponse function * * xResponse method is made to return jQuery ajax response * * @param {string} url [your url or file] * @param {object} your ajax param * @return {mix} [ajax response] */ $.extend({ xResponse: function(url, data) { // local var var theResponse = null; // jQuery ajax $.ajax({ url: url, type: 'POST', data: data, dataType: "html", async: false, success: function(respText) { theResponse = respText; } }); // Return the response text return theResponse; } }); // set ajax response in var var xData = $.xResponse('temp.html', {issession: 1,selector: true}); // see response in console console.log(xData);
możesz zrobić tak duży, jak chcesz ...
źródło
ajaxObj['responseText']
nie istnieje, kiedy definiujeszvar ajaxResponse
Widziałem tutaj odpowiedzi i chociaż były pomocne, nie były one dokładnie tym, czego chciałem, ponieważ musiałem zmienić wiele mojego kodu.
To, co mi się udało, zrobiło coś takiego:
function isSession(selector) { //line added for the var that will have the result var result = false; $.ajax({ type: "POST", url: '/order.html', data: ({ issession : 1, selector: selector }), dataType: "html", //line added to get ajax response in sync async: false, success: function(data) { //line added to save ajax response in var result result = data; }, error: function() { alert('Error occured'); } }); //line added to return ajax response return result; }
Nadzieja pomaga komuś
anakin
źródło
Chociaż wszystkie podejścia dotyczące użycia
async: false
nie są dobre z powodu jego dezaktualizacji i zablokowały stronę, dopóki żądanie nie wróci. Oto dwa sposoby, aby to zrobić:1st: Zwróć całą odpowiedź ajax w funkcji, a następnie użyj
done
funkcji do przechwycenia odpowiedzi, gdy żądanie zostanie zakończone. (ZALECANE, NAJLEPSZY SPOSÓB)function getAjax(url, data){ return $.ajax({ type: 'POST', url : url, data: data, dataType: 'JSON', //async: true, //NOT NEEDED success: function(response) { //Data = response; } }); }
ZADZWOŃ POWYŻEJ TAK:
getAjax(youUrl, yourData).done(function(response){ console.log(response); });
W PRZYPADKU WIELU POŁĄCZEŃ AJAX WYKORZYSTAJ
$.when
:$.when( getAjax(youUrl, yourData), getAjax2(yourUrl2, yourData2) ).done(function(response){ console.log(response); });
2nd: Przechowuj odpowiedź w pliku cookie, a następnie poza wywołaniem Ajax pobierz wartość tego pliku cookie. (NIE ZALECANE)
$.ajax({ type: 'POST', url : url, data: data, //async: false, // No need to use this success: function(response) { Cookies.set(name, response); } }); // Outside of the ajax call var response = Cookies.get(name);
UWAGA: W powyższym przykładzie
jquery cookies
używana jest biblioteka, która jest dość lekka i działa równie zgryźliwie. Oto link https://github.com/js-cookie/js-cookieźródło
Dodaj
async: false
do listy atrybutów. Zmusza to wątek javascript do czekania, aż zwrócona wartość zostanie pobrana przed przejściem dalej. Oczywiście nie chciałbyś tego robić w każdych okolicznościach, ale jeśli potrzebna jest wartość przed kontynuowaniem, to wystarczy.źródło
async: false
. To blokuje wszystko na stronie na czas pobierania. Wiesz, co oznacza A w AJAX: asynchroniczny. Prawidłowa odpowiedź byłaby taka, że OP musisuccess()
poprawnie używać wywołania zwrotnego.async: false
dlaczego jQuery zaimplementował tę opcję? Jeśli nie ładuję dużych ilości danych na stronę i po prostu obsługuję zdarzenie użytkownika, jest w porządku, że blokuje wszystko inne w krótkim czasie dla tego konkretnego użytkownika. nic w tym złego i nic złego. (jeśli zostanie użyty poprawnie, nie zablokuje niczego, ponieważ w tym konkretnym czasie nie będą wykonywane żadne inne akcje dla tego konkretnego użytkownika)To jest dość stare i brzydkie, nie rób tego. Powinieneś użyć callbacków: https://stackoverflow.com/a/5316755/591257
Miałem ten sam problem, rozwiązałem go w ten sposób, używając globalnego var. Nie jestem pewien, czy jest najlepszy, ale na pewno działa. W przypadku błędu otrzymasz pusty ciąg (myVar = ''), więc możesz to obsłużyć w razie potrzeby.
var myVar = ''; function isSession(selector) { $.ajax({ 'type': 'POST', 'url': '/order.html', 'data': { 'issession': 1, 'selector': selector }, 'dataType': 'html', 'success': function(data) { myVar = data; }, 'error': function() { alert('Error occured'); } }); return myVar; }
źródło
async: false
tutaj, ponieważ w trybie asynchronicznym nie ma gwarancji, żedata
zostanie zapisanymyVar
przedmyVar
zwróceniem.// Common ajax caller function AjaxCall(url,successfunction){ var targetUrl=url; $.ajax({ 'url': targetUrl, 'type': 'GET', 'dataType': 'json', 'success': successfunction, 'error': function() { alert("error"); } }); } // Calling Ajax $(document).ready(function() { AjaxCall("productData.txt",ajaxSuccessFunction); }); // Function details of success function function ajaxSuccessFunction(d){ alert(d.Pioneer.Product[0].category); }
może to pomóc, utwórz wspólną funkcję AJAX i dołącz funkcję, która wywoła wywołanie Ajax po pomyślnym zakończeniu, patrz przykład
źródło
Z pomocą tutaj
function get_result(some_value) { var ret_val = {}; $.ajax({ url: '/some/url/to/fetch/from', type: 'GET', data: {'some_key': some_value}, async: false, dataType: 'json' }).done(function (response) { ret_val = response; }).fail(function (jqXHR, textStatus, errorThrown) { ret_val = null; }); return ret_val; }
Mam nadzieję, że to komuś trochę pomoże.
źródło
async: false,
jest prehistoryczne i jest przestarzałe od wersji jQuery v1.8, prawdopodobnie nikomu nie pomożeCześć, spróbuj async: false w wywołaniu Ajax.
źródło