【问题标题】:jquery - return value using ajax result on successjquery - 成功时使用ajax结果返回值
【发布时间】:2011-03-19 04:16:28
【问题描述】:

我对 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 == ""(这将表明已选择 None 选项)并从总数中扣除金额并删除带有选择名称的会话。

这就是问题开始的地方 - 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 是否会从函数返回结果 - 因为它似乎不起作用 - 但是,如果我将“数据”放入成功: alert() 部分 - 它似乎确实返回了正确的值。

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


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

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

但由于某种原因 - 它不起作用 - 有什么想法吗?

【问题讨论】:

标签: jquery


【解决方案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
}

【讨论】:

  • 您可以从 AJAX 请求中返回一个值,但前提是您将其设为 非异步(设置选项 async: false)。在某些情况下,不需要进行异步调用。更多关于 jquery.ajax() 文档 api.jquery.com/jQuery.ajax ,而不是 As of jQuery 1.8, the use of async: false with jqXHR ($.Deferred) is deprecated;
  • “非异步”当然也可以称为“同步”;)
  • 在您建议的两种方法中; IE。成功运行函数,那么你必须为不同的场景编写多个ajax。这无助于创建全局 ajax 包装器引擎。
  • 看来,async: false 现在已被弃用,所有处理都需要在回调函数中完成。
【解决方案2】:

有很多方法可以获得 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);

你可以把它变大...

【讨论】:

  • 好主意,但是当您定义 var ajaxResponse 时,ajaxObj['responseText'] 不存在
  • 完美!!你的第一个解决方案救了我
  • 第二种方法是 100% 好的! ;)
  • 从 jQuery 1.8 开始,不推荐使用 async: false !
【解决方案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 的方法都不好,因为它已被弃用并卡住页面,直到请求返回。因此,这里有两种方法:

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

【讨论】:

  • 第一种方法是输出我的整个 PHP 代码而不是 echo 输出。
【解决方案5】:

编辑:这很旧,而且很丑,不要这样做。你应该使用回调:https://stackoverflow.com/a/5316755/591257

编辑 2:fetch API

遇到同样的问题,使用全局变量以这种方式解决。不确定它是否是最好的,但肯定有效。出错时您会得到一个空字符串 (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;
}

【讨论】:

  • 这里还需要添加async: false,因为在异步模式下,不能保证data在返回myVar之前保存到myVar中。
  • @low_rents,感谢您的评论。我在从 ajax 调用返回值时遇到问题,这是我发现的第一个(经过多次)提到async: false 的线程。非常适合我。
  • 绝对是@low_rents,但请不要相信这个答案,从那以后事情发生了很大变化。
【解决方案6】:

async: false 添加到您的属性列表中。这会强制 javascript 线程在继续之前等待,直到检索到返回值。显然,您不会希望在所有情况下都这样做,但如果在继续之前需要一个值,这将执行此操作。

【讨论】:

  • 你永远不应该设置async: false。这会在检索期间阻止页面上的所有内容。你知道 AJAX 中的 A 代表什么:异步。正确的答案是 OP 需要正确使用 success() 回调。
  • 我承认一切都必须等待。在某些情况下,调用函数可能需要返回值,例如添加新记录,需要返回记录id。一旦你知道了规则,你就知道它们什么时候可以被打破。永远不要把话说绝了。这是另一个同意的人。 (stackoverflow.com/questions/3880361/…)
  • @CharlesWood 专为那些无法掌握 ajax 异步特性的人准备的。
  • @nietonfir :如果你永远不应该使用async: false,为什么jQuery 会实现这个选项?如果我不将大量数据加载到页面并仅处理用户事件,那么它可以在短时间内为该特定用户阻止其他所有内容。没有错,也没有什么不好。 (如果使用得当,它不会阻止任何事情,因为在那个特定时间不会发生该特定用户的其他操作)
  • @northkildonan 不,这不好。同步 AJAX 请求是错误的。它用你无法控制的东西阻塞了整个 javascript 线程。您无法控制处理请求可能花费的时间:连接可能不可靠,服务器可能需要比预期更长的时间,等等。它在 jQuery 中的 唯一原因是您可能需要在页面卸载时保存数据(如果需要更长的时间并不重要,因为用户已经表达了离开页面的愿望)。看看 jQuery 单元测试吧……
【解决方案7】:

here的帮助下

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 起已被弃用,它可能对任何人都没有帮助
【解决方案8】:
// 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 调用成功时调用的函数,参见示例

【讨论】:

    【解决方案9】:

    您好,在您的 ajax 调用中尝试 async:false..

    【讨论】:

      猜你喜欢
      • 2011-11-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-07-13
      • 1970-01-01
      相关资源
      最近更新 更多