Jquery - возвращаемое значение с использованием результата ajax при успешном завершении

У меня есть небольшая проблема с функцией jquery $.ajax().

У меня есть форма, в которой каждый щелчок на переключателе или выборе в раскрывающемся меню создает переменную сеанса с выбранным значением.

Теперь - у меня есть одно из выпадающих меню, у которого есть 4 варианта - первый (с меткой Нет) имеет value = "", у других есть свои идентификаторы.

То, что я хочу сделать, это вариант None (с пустым значением), чтобы удалить сеанс и другие для его создания, но только если сеанс с этим конкретным именем выбора еще не существует - поскольку все остальные параметры имеют одинаковую сумму назначенный ему - он просто указывает, какой из них был выбран.

Я не уверен, что это имеет смысл - но посмотрите на код - возможно, это сделает его более ясным:

$("#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();
});

так что, прежде всего, когда #add_ons выбирает меню, запускает "изменение", мы получаем некоторые значения из нескольких элементов для вычислений.

мы получаем атрибут метки опции из нашего выбора, в котором хранится значение, которое должно быть добавлено к общему числу, имя выбранного для создания сеанса с этим именем и значением, чтобы позже проверить, какой из них выбран.

теперь - мы проверяем, будет ли val == "" (что указывает на то, что опция None выбрана), и мы вычитаем сумму из общего числа, а также удалим сеанс с именем выбора.

После этого начинается проблема - инструкция else.

Else - мы хотим проверить, возвращает ли функция isSession() имя нашего селектора 0 или 1 - если оно возвращает 0, то мы добавляем к сумме значение, сохраненное в атрибуте метки, но если оно возвращает 1 - что предполагает, что сеанс уже существует, - тогда мы только изменяем значение этого сеанса, воссоздавая его, но сумма не добавляется к нему.

Теперь функция isSession выглядит следующим образом:

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');
        }
    });
}

Теперь - проблема в том, что я не знаю, вернет ли результат из функции return результат функции, поскольку он не работает, однако, если я положил "данные" в успех: раздел в предупреждение - он, кажется, возвращает правильное значение.

Кто-нибудь знает, как вернуть значение из функции, а затем сравнить его в следующем утверждении?


Спасибо, ребята, я пробовал это следующим образом:

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');
        }
    });
}

то функция updateResult():

function updateResult (data) { result = data; }

result - глобальная переменная, которую я тогда пытаюсь читать:

$("#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();
    });

но по какой-то причине - это не сработает - любая идея?

Ответ 1

Проблема в том, что вы не можете вернуть значение из асинхронного вызова, например запроса AJAX, и ожидать, что он будет работать.

Причина в том, что код, ожидающий ответа, уже выполнен к моменту получения ответа.

Решение этой проблемы - запустить необходимый код внутри обратного вызова success:. Таким образом, он получает доступ к data только тогда, когда он доступен.

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');
        }
    });
}

Другая возможность (что фактически то же самое) заключается в вызове функции внутри вашего обратного вызова success:, который передает данные, когда он доступен.

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
}

Ответ 2

Есть много способов получить ответ JQuery AJAX. Я делюсь с вами двумя общими подходами:

Первый:

используйте async = false и внутри функции возвращайте ajax-объект, а затем получите ответ ajax-object.responseText

/**
 * 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);
});

Во- вторых:

используйте метод $.extend и создайте новую функцию, такую как ajax

/**
 * 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);

Вы можете сделать его настолько большим, насколько захотите...

Ответ 3

Я видел ответы здесь и хотя они были полезны, они не были именно тем, что я хотел, так как мне пришлось изменить много кода.

Что сработало для меня, делал что-то вроде этого:

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;
}

Надежда помогает кому-то

Анакин

Ответ 4

Добавьте async: false в список ваших атрибутов. Это заставляет поток javascript ждать, пока возвращаемое значение не будет извлечено, прежде чем двигаться дальше. Очевидно, что вы не захотите делать это при любых обстоятельствах, но если для продолжения необходимо значение, это сделает это.

Ответ 5

Это довольно старый и уродливый, не делайте этого. Вы должны использовать обратные вызовы: fooobar.com/questions/19901/...
Имела ту же проблему, решила ее таким образом, используя глобальный var. Не уверен, что он лучший, но верно работает. При ошибке вы получаете пустую строку (myVar = ''), поэтому вы можете обращаться с ней по мере необходимости.

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;
}

Ответ 6

// 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);
}

он может помочь, создать общую функцию вызова ajax и приложить функцию, которая вызывается при успешном вызове ajax, см. пример

Ответ 7

Хотя все подходы относительно использования async: false не годятся из-за его устаревания и застряли на странице, пока запрос не вернется. Таким образом, вот 2 способа сделать это:

1-й: возврат целого ajax-ответа в функцию, а затем использование функции done для захвата ответа по завершении запроса (РЕКОМЕНДУЕТСЯ, ЛУЧШИЙ СПОСОБ)

function getAjax(url, data){
    return $.ajax({
        type: 'POST',
        url : url,              
        data: data,
        dataType: 'JSON',
        //async: true,  //NOT NEEDED
        success: function(response) {
            //Data = response;
        }
    });
 }

НАЗВАТЬ ВЫШЕ, КАК ТАК:

getAjax(youUrl, yourData).done(function(response){
    console.log(response);
});

ДЛЯ НЕСКОЛЬКИХ ВЫЗОВОВ AJAX ИСПОЛЬЗУЙТЕ $.when :

$.when( getAjax(youUrl, yourData), getAjax2(yourUrl2, yourData2) ).done(function(response){
    console.log(response);
});

2-й: Сохраните ответ в куки, а затем вне вызова ajax получите это значение куки. (НЕ РЕКОМЕНДУЕТСЯ)

        $.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);

ПРИМЕЧАНИЕ. В приведенном выше примере используется библиотека jquery cookies Она довольно легкая и работает как snappy. Вот ссылка https://github.com/js-cookie/js-cookie

Ответ 8

С помощью отсюда

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;
}

Надеюсь, это поможет кому-нибудь немного.

Ответ 9

Привет, попробуйте async: false в вашем вызове ajax..