jQuery-成功使用Ajax结果返回值


95

我有一个jQuery $ .ajax()函数的小问题。

我有一个表单,其中每次单击单选按钮或从下拉菜单中进行选择都会创建具有所选值的会话变量。

现在-我有一个下拉菜单,其中有4个选项-第一个菜单(标签为None)具有value =“”,其他具有其ID。

我要执行的操作是使用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 ==“”(这表明已选择“无”选项),然后从总数中扣除金额,并删除带有选择名称的会话。

在这之后问题就开始了-else语句。

否则-我们要检查具有选择器名称的isSession()函数是否返回0或1-如果返回0,则将存储在label属性中的值加到总计中,但是如果返回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”是否会从函数中返回结果-因为它似乎不起作用-但是,如果我将“ data”放在success:部分中,警告-它似乎返回正确的值。

有谁知道如何从函数中返回值,然后在下一条语句中进行比较?


谢谢大家-我已经尝试过以下方式:

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){结果=数据;}

结果-是全局变量-然后尝试读取:

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

但由于某种原因-它不起作用-任何想法?



它可能有助于解决此问题:stackoverflow.com/questions/14220321/…–
mirzaei.sajad

Answers:


114

问题在于您无法从异步调用(如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
}

11
您可以从AJAX请求中返回一个值,但这仅在您使其非异步的情况下(设置选项async: false)。在某些情况下,不需要异步调用。有关jquery.ajax()doc api.jquery.com/jQuery.ajax的更多信息,请不要关注As of jQuery 1.8, the use of async: false with jqXHR ($.Deferred) is deprecated;
Adrien

48
“非异步”当然也可以称为“同步”;)
Charles Wood

您建议使用两种方法;即。成功运行该函数,则必须针对不同的情况编写多个ajax。这将不利于创建全局ajax包装器引擎。
wpcoder

似乎,异步:现在不建议使用false,所有处理都需要在回调函数中完成。
Puneet Lamba

31

有很多方法可以获取jQuery AJAX响应。我将与您分享两种常用方法:

第一:

使用async = false并在函数内返回ajax-object并稍后获取响应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);

您可以根据需要将其放大...


好主意,但ajaxObj['responseText']定义时不存在var ajaxResponse
mu3 2014年

完善!!您的第一个解决方案救了我
Kallel Omar

第二种方法是100%A OK!;)
Schalk Keun

7
从jQuery 1.8开始,不赞成使用async:false!
gatteo '17

10

我在这里看到了答案,尽管有帮助,但它们并不是我想要的,因为我不得不更改很多代码。

对我有用的事情是在做这样的事情:

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
您实际上只是关闭了异步
Weijing Jay Lin

4

尽管所有有关使用的方法async: false都因其过时而不好用,并阻塞了页面直到请求返回。因此,有两种方法可以做到这一点:

第一个:在函数中返回整个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);
});

第二步:将响应存储在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


3

添加async: false到您的属性列表。这将迫使javascript线程等待,直到获取返回值,然后再继续。显然,您并不想在每种情况下都执行此操作,但是如果在继续操作之前需要某个值,则可以执行此操作。


3
你永远都不要动async: false。这会在检索期间阻止页面上的所有内容。您知道AJAX中的A代表什么:异步。正确的答案是OP需要success()正确使用回调。
nietonfir 2013年

2
我承认事实是一切都必须等待。在某些情况下,调用函数可能需要返回值,例如添加新记录和需要返回记录ID。一旦知道了规则,便知道何时可以打破规则。永远不要把话说绝了。这是其他同意的人。(stackoverflow.com/questions/3880361/...
流氓

1
@CharlesWood只适合那些无法掌握ajax异步特性的人。
nietonfir 2014年

1
@nietonfir:如果您永远不要使用,async: false为什么jQuery会实现此选项?如果我不向页面加载大量数据并仅处理用户事件,则可以在短时间内阻止该特定用户的所有其他事件。没错,没什么不好的。(如果使用得当,它将不会阻止任何内容,因为在该特定时间不会发生针对该特定用户的其他操作)
low_rents 2014年

1
@northkildonan不,这不好。同步AJAX请求不正确。它使用您无法控制的内容来阻止整个javascript线程。您无法控制处理请求的时间:连接可能不可靠,服务器所花费的时间可能比预期的长,等等。在jQuery中的唯一原因是您可能需要保存数据页面卸载(唯一的地方,它是否需要更长的时间并不重要,因为用户已经表达了离开页面的愿望)。只要看看jQuery单元测试…
nietonfir 2014年

3

这已经很老了,很丑,不要这样做。您应该使用回调: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;
}

3
您还需要在async: false此处添加内容,因为在异步模式下,不能保证将data其保存到返回myVar之前myVar
low_rents

2
// 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调用成功时调用,请参见示例


1

有了这里的帮助

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

希望这对某人有所帮助。


async: false,自jQuery v1.8起就开始使用,并且已弃用,它可能无济于事
Alon Eitan

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.