【问题标题】:javascript/jquery scope has me stumpedjavascript/jquery 范围让我很难过
【发布时间】:2010-10-11 21:42:45
【问题描述】:

我已将一个常见的 ajax 调用包装到一个函数中。它 ping 一个脚本,返回 JSON。

但是,在我的一生中,我似乎无法让 JSON 对象成为函数的返回值。

一定是我想念的相当简单的东西,但我这辈子都做不出来。

function queryCostCenter(user_id, currency_id, country_id){

   var output = null;
   var destinations = new Array();

   var destination = { qty:1, country: country_id };
   destinations.push(destination)           


   var data = {
                 destinations : $.toJSON(destinations),
                 user_id : user_id,
                 currency_id: currency_id
              };

   $.ajax({
         data: data,
         type: 'POST',
         url: '/lib/ajax/ajax_prepaid_cost_calculator.php',
         success: function(data) {         
            output = data;
            alert(output);
         }
   });

   alert(output);

   return json;

}

ajax() 调用内部的 alert() 显示 json 对象,但是如果在函数外部尝试和警告,和/或从 ajax() 调用内部返回响应,其值为 null?!

任何帮助/指针将不胜感激。

【问题讨论】:

标签: javascript jquery scope


【解决方案1】:

典型错误。 Ajax调用后的代码

alert(output);
return json;

被执行, Ajax 调用返回之前。它是异步(意思是,它不会在您将其放入代码的时间和位置执行,而是在稍后的某个时间点执行)。您可以为您的函数提供回调,如下所示:

// cb is our callback - it is a function
function queryCostCenter(user_id, currency_id, country_id, cb){ 
   var destinations = new Array();

   var destination = { qty:1, country: country_id };
   destinations.push(destination)           

   var data = {
                 destinations : $.toJSON(destinations),
                 user_id : user_id,
                 currency_id: currency_id
              };

   $.ajax({
         data: data,
         type: 'POST',
         url: '/lib/ajax/ajax_prepaid_cost_calculator.php',
         success: function(result) { // or just `success: cb`
            cb(result); // execute the callback with the returned data
         }
   });   
}

然后:

queryCostCenter(some_value, some_value, some_value, function(result) {
    // do something with the returned data.
});

或者把所有的逻辑都放在Ajax调用的成功处理器中。但是有了回调函数,你就更灵活了,你可以更好地复用这个函数。


这是一个非常常见的回调用例。由于您不知道何时 Ajax 调用将完成,因此您将一个函数传递给应该在返回一些结果时运行的Ajax 调用。你对success 处理程序没有做任何其他事情:它是一个在调用完成时调用的函数。

【讨论】:

  • 你应该提到'async'选项。
  • 我会提到它。如果将 'async' 选项设置为 false,则脚本将暂停,直到请求完成。在data: data 的上方添加async: false,,您的代码将按原样运行。这里有一些阅读。 api.jquery.com/jQuery.ajax
  • @sje397:老实说,我认为async 选项是无稽之谈。我没有进行任何测量,但我无法想象 Ajax 请求会在 100 毫秒内完成(这是一段代码应该运行的最长时间,否则 UI 对用户来说似乎很慢)。 可能在某些情况下,此选项具有优势。但是 Ajax 请求的全部意义在于异步。对于该领域的新开发人员,async 可能很有吸引力,因为他们不知道更好......我会尽量避免使用它。
  • King:我完全同意——这就是我想到的那种说法。由于在文档中很容易找到,我认为值得一提。我从来没有理由使用它。尽管在这种情况下它确实“使代码工作”,但重构代码以使用回调是一个更好的选择,如您所示。
【解决方案2】:

$.ajax() 是异步的。 简而言之:函数块外的 alert(output) 很可能会在 async 方法返回任何结果之前被调用,因此仍然为 null。

【讨论】:

  • @danlefree 如果需要,您可以对所有正确答案进行投票,而不仅仅是第一个。 :)
【解决方案3】:

这不是范围问题。这是您的 Ajax 调用的异步特性。您的 queryCostCenter 函数可能会在 Ajax success 处理程序运行之前返回。您需要在 success 回调中启动所有后 Ajax 逻辑。

【讨论】:

    【解决方案4】:

    您实际上并没有获取并转换回 JSON,只是一个大文本块。查看 getJSON 的文档,这是您需要使用的。

    http://api.jquery.com/jQuery.getJSON/

    $.getJSON({
         '/lib/ajax/ajax_prepaid_cost_calculator.php',
         {data:data}
         , function(data) {   
            alert(data.jsonElement);
            //do something with your data HERE
    
         }
    

    });

    jsonElement 是 JSON 数组中的一个元素

    【讨论】:

      猜你喜欢
      • 2011-03-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-10-19
      • 2020-04-05
      • 2020-05-20
      相关资源
      最近更新 更多