jquery - возвращает значение, используя ajax-результат в случае успеха - PullRequest
81 голосов
/ 21 июля 2010

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

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

Теперь - у меня есть одно из выпадающих меню, которые имеют 4 варианта - первый (с меткой 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.

Иначе - мы хотимчтобы проверить, возвращает ли функция 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 ():

функция 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();
    });

, но по какой-то причине - она ​​не работает - какая-то идея?

Ответы [ 9 ]

101 голосов
/ 21 июля 2010

Проблема в том, что вы не можете вернуть значение из асинхронного вызова, такого как запрос 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
}
29 голосов
/ 21 сентября 2012

Есть много способов получить ответ 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);
});

Второй:

использовать $. Продлить метод и сделать новую функцию, как 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);

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

8 голосов
/ 12 марта 2015

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

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

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

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

Анакин

3 голосов
/ 02 ноября 2013

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

2 голосов
/ 25 февраля 2013
// 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, см. Пример

2 голосов
/ 18 февраля 2013

Это довольно старо, и уродливо, не делай этого.Вы должны использовать обратные вызовы: https://stackoverflow.com/a/5316755/591257
Была та же проблема, решенная таким образом, используя глобальную переменную.Не уверен, что это лучше, но, безусловно, работает.В случае ошибки вы получаете пустую строку (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;
}
0 голосов
/ 11 июля 2019

С помощью здесь

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

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

0 голосов
/ 19 мая 2019

Хотя все подходы относительно использования 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-й: Сохраните ответ в файле cookie, а затем вне вызова ajax получите это значение файла cookie (НЕ РЕКОМЕНДУЕТСЯ)

        $.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. Она достаточно легкая и работает быстро. Вот ссылка https://github.com/js-cookie/js-cookie

0 голосов
/ 10 апреля 2014

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

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