【问题标题】:Return $.get data in a function using jQuery使用 jQuery 在函数中返回 $.get 数据
【发布时间】:2010-12-11 00:08:58
【问题描述】:

我正在尝试调用一个包含 jQuery 代码的函数。我希望这个函数返回 jQuery 语句的结果。它不起作用,我正在尝试找出原因。

function showGetResult (name) {
    var scriptURL = "somefile.php?name=" + name;
    return $.get(scriptURL, {}, function(data) { return data; });
}

alert (showGetResult("John"));

警报显示“[object XMLHttpRequest]”。但是,如果我在函数之外单独运行 jQuery 语句,它可以正常工作 -> $.get(scriptURL, {}, function(data) { alert(data); })

我希望能够通过将其放入返回$.get 数据的函数中来重用此代码。我在这里犯了什么根本性错误?

【问题讨论】:

    标签: jquery xmlhttprequest


    【解决方案1】:

    你有几个不同的错误。首先,$.get 不返回回调函数的返回值。它返回 XHR 对象。其次,get 函数不是同步的,它是异步的,因此 showGetResult 可能会在 get 完成之前返回。第三,您不能将回调内部的某些内容返回到外部范围。但是,您可以在外部范围内绑定变量并在回调中设置它。

    要获得所需的功能,您需要使用 $.ajax 并将 async 选项设置为 false。然后可以在外部作用域中定义一个变量,并在ajax回调中赋值,从函数中返回这个变量。

    function showGetResult( name )
    {
         var result = null;
         var scriptUrl = "somefile.php?name=" + name;
         $.ajax({
            url: scriptUrl,
            type: 'get',
            dataType: 'html',
            async: false,
            success: function(data) {
                result = data;
            } 
         });
         return result;
    }
    

    不过,您可能会得到更好的服务,弄清楚如何在回调函数本身中执行您想要的操作,而不是从异步调用更改为同步调用。

    【讨论】:

    • 感谢您的彻底分解。切换到同步和使用外部范围内的变量来传递数据的组合解决了我的问题。
    • 这很好,但请注意,通过切换到同步,您可能会导致浏览器在等待响应时锁定。这可能是一个错误,除非您知道您的用户将始终处于闪电般的快速连接上,并且您的服务器永远不会被淹没。这也与 AJAX 的全部意义相反——它旨在使 Web 应用程序更具响应性,但这种变化可能会使您的应用程序的响应性大大降低。
    • 我同意@JacobM 的观点,如果可能的话,最好使用异步并在回调中处理您的操作。
    • 差不多五年后,我不得不回过头来评论自己上面使用同步而不是异步。我是多么的无知。 ;-)
    【解决方案2】:

    您所犯的根本错误是 AJAX 调用是异步进行的,因此当您返回时,结果尚未准备好。要完成这项工作,您可以像这样修改您的代码:

    $(function() {
        showGetResult('John');
    });
    
    function showGetResult (name) {
        $.get('somefile.php', { 
            // Pass the name parameter in the data hash so that it gets properly
            // url encoded instead of concatenating it to the url.
            name: name 
        }, function(data) { 
            alert(data); 
        });
    }
    

    【讨论】:

    • 任务是返回这个“数据”结果,而不是从服务器加载时打印它。
    • 这只是在回调中使用数据,而不是在回调之外“返回”。
    【解决方案3】:

    看起来你想要同步请求: How can I get jQuery to perform a synchronous, rather than asynchronous, Ajax request?

    或者,您可能希望将回调传递给您的函数:

    function showGetResult (name, callback) {
      var scriptURL = "somefile.php?name=" + name;
      return $.get(scriptURL, {}, callback);
    }
    
    showGetResult("John", function(data){ alert(data); });
    

    【讨论】:

      【解决方案4】:

      根本错误是 AJAX 的“异步”部分。因为您不知道服务器需要多长时间才能发回响应,所以 AJAX 方法永远不会“阻塞”——也就是说,您不会呼叫服务器而只是坐在那里等待结果。相反,您继续做其他事情,但是您设置了一个称为“回调”的方法,该方法将在结果返回时触发。此方法负责对数据执行任何需要执行的操作(例如将其注入页面)。

      【讨论】:

        【解决方案5】:

        这是错误的做法。 function(data) 是一个回调函数,所以每当 return $.get 将执行.. 回调函数可能不会被调用。

        最好从 function(data) 方法调用您的发布数据获取函数。

        【讨论】:

          【解决方案6】:

          一种有效的方法是使用 jQuery 的 Deferred 方法,同步/异步请求到服务器并等待 deferred.resolve() 然后返回延迟的 promise 对象。看起来有点乏味,但一点点研究肯定对大数据有帮助。 (tvanfosson的功能在这种情况下效果很好,但是当我在处理google分析数据时,大量的信息让我抓狂,因此我需要找到这个解决方案)

               function showResults(name) { 
                  var deferred = $.Deferred, requests = [];
          
                  requests.push($.ajax({url:"/path/to/uri/?name=" + name, type: "GET", async: false}).done(function(d) { 
                   //alert or process the results as you wish 
                  }));
                  $.when.apply(undefined, requests).then(function() { deferred.resolve(); }); 
                  return deferred.promise();
          
              }
          

          返回的 promise 对象也可以与$.when(showResults('benjamin')).done(function() { }); 一起用于后期修改(如图表/图形设置等)。完全可重复使用。 您也可以将此函数放在 $.deferred 请求的循环中,例如,

                  function updateResults() { 
                       var deferred = $.Deferred, requests = [];
                       requests.push($.ajax(url:"/path/to/names/?nameArr=" + jsonArrOfNames, type: "GET", async: false}).done(function(res) {  requests.push(showResults(res[0]));}) );
                       $.when.apply($, requests).then(function() { deferred.resolve(); }); 
                       return deferred.promise();
                      }
          

          【讨论】:

            猜你喜欢
            • 2015-08-02
            • 2013-07-08
            • 1970-01-01
            • 1970-01-01
            • 2022-07-10
            • 1970-01-01
            • 2015-07-30
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多