【问题标题】:Understanding jquery callbacks了解 jquery 回调
【发布时间】:2011-01-17 00:21:29
【问题描述】:

我很难理解 javascript 回调应该如何工作。我正在使用以下代码从 MySQL 数据库中获取值:

  $.post("getResults.php", { x: 100, y: 200},       
   function(arrayOfValues){  
      alert( arrayOfValues[2] )         
   }, 'json');

alert() 返回正确的值,并且按预期运行。但是,我不明白 arrayData[2] 的值如何传递或返回到我程序的其他部分(我所做的尝试没有奏效)。

我已经阅读了jquery help 和许多 SO 问题和答案,但我不明白回调是如何工作的。

在这种情况下,我希望我的主程序可以访问 arrayOfValues[2]。

【问题讨论】:

  • 我意识到问题出在我获取数据所需的时间长度上。无论如何我可以让我的程序等到它收到 POST 数据后再继续下一部分吗?

标签: javascript jquery callback


【解决方案1】:

$.post() 是异步(非阻塞)调用,这意味着函数立即返回(不等待服务器响应)并执行下一个javascript 代码。 当来自服务器的响应到达时,您的回调函数被调用,响应...

假设你想在一个 div 中显示内容:

$.post('url.php', {}, function(content) {
  $('#div_id').html(content);
});

// or shorter:
$('#div_id').load('url.php', {});

或者你可以拥有一个具有某种逻辑的对象,并将对象的方法注册为回调:

function MyHandler(msgElement) {
  var sum = 0;
  this.onSuccess = function(content) {
    sum = sum + content[0];
    if (sum > 100) {
      msgElement.html('Sum has reached 100 !');
    }
  };
  this.otherMethod = function() {
    alert('Current sum is:' + sum);
  };
}

var handler = new MyHandler($('#my_div'));

// do the request
$.post('url.php', {}, handler.onSuccess, 'json');

// you can call any method of handler object using global variable handler
// or passing a reference (handler object) to any other object
// notice, if you call this method immediately after sending the request,
// the sum var is likely to be 0, as the response has not arrived yet...
handler.otherMethod();

基本上,您有很多选择。因此,如果您需要更多信息,请具体说明您想要响应的内容...

【讨论】:

  • 感谢您的回答。我要做的是将数组arrayData 设置为稍后可以在我的javascript 中访问的值。所以如果我写this.onSuccess = function(arrayData){a = arrayData[2]; return x },我可以在其他地方访问x吗?
  • 当响应到达时,浏览器调用回调(this.onSuccess 函数),因此返回任何值没有意义 - 您无权访问它。你读过我的代码吗?第二个例子正在做,你需要的 - 通过闭包访问sum 变量。然后,这个 MyHandler 的任何其他函数方法也可以访问这个 sum 变量......查看我更新的答案,我添加了 otherMethod 以表明......
【解决方案2】:
var foo;

$.post("getResults.php", { x: 100, y: 200 }, function(data) {  
    foo = data;       
}, 'json');

响应数据将存储到foo 变量中。但是请注意,这是一个异步回调函数,当 HTTP 响应到达时会调用它。请务必了解,在 HTTP 响应到达且回调函数完成之前,您不能使用 foo 变量

【讨论】:

  • 我如何知道响应何时到达?我已经意识到我的问题的根源是在值返回之前使用它。
  • @celenius 是的,我认为那是你的问题 :) 好吧,拥有异步函数的全部意义在于能够在未来未知的时刻执行代码。您不知道响应将会到达,这就是您首先使用异步回调的原因。话虽如此,您现在有多种选择。例如,您可以通过超时来延迟您的代码,直到填充了 foo 变量。
  • 嗯。因此,如果我这样构造它:` $.ajax({ type:"POST",url:"getLatLongv2.php", data:{ latUser: latArrayVal, longUser: longArrayVal}, async: false, success: function(arrayData) { alert(arrayData[2]); arrayValue = arrayData[2];}, dataType:'json' });` 那会是一种方法吗?
  • @celenius 这实际上取决于您要如何处理响应数据。你能详细说明一下吗?
【解决方案3】:

回调,让我试着用你能理解的方式解释一下。

  • 首先,您需要了解如何将函数分配给变量而不执行。

这允许您传递函数并仅在需要时执行它们,这是我如何将函数传递给变量而不执行它的示例:

a = function(){}

这是一个小例子,也是最常见的,你可以像 a() 这样调用函数,添加 () 告诉函数执行。

  • 现在您应该明白了,您可以将这些变量传递给另一个函数,但不能调用它们

以下示例向您展示了如何在执行时将函数传递给上述函数a

b = function(){}
b(a);
  • 下一步是能够创建匿名函数,这将允许您将函数分配给变量,同时传递给另一个函数

匿名函数在编写它时并未分配,而是在外部函数范围内解析时分配。

上面的内容我有点难以理解,但希望这个例子能解决它。

a(
    function(){}
);

上面和b(a)的例子一样,除了a现在是一个匿名函数,只赋值给b内的变量,即外层函数。

jQuer'ies API 严重依赖匿名函数,因为它易于使用并与 jQuery 核心和用户代码分离,用户不需要过度依赖 jQuery 的主要代码,而是通过回调来允许 jQuery而是连接到您的代码。

使用类似方法将数据传入和传出函数的函数示例如下:

JoinUser = function(Firstname,Lastname,callback)
{
     Fullname = Firstname + " " + Lastname;
     callback(Fullname);
}

JoinUser("Robert","Pitt",function(Fullname)
{
    alert(Fullname); //Robert Pitt
})

上面的例子只是大致展示了 jQuery 的风格是如何工作的,而不是回调的最重要的好处,那就是 Ajax。

Ajax 可以暂停一个 javascript 脚本,直到它的数据被接收到,例如:

Result = RequestPage("Contacts");

当 Ajax 看到这一行时,它必须等待 RequestPage 返回结果,因为进一步向下的编码预计需要这个值,所以我们必须等待在 JavaScript 继续之前从服务器返回数据,这可能会持续几秒钟并导致 UI 动作异常。

我们解决这个问题的方法是向函数发送回调,并告诉它在完成后调用,因为我想处理应用程序的其余部分。

RequestPage("Contacts",function(){});

所以现在 JavaScript 继续向下执行它需要的任务的页面,在 RequestPage 函数中,它的布局如下:

function RequestPage(page,callback)
{
    //..
        request.oncomplete = callback;
    //..
}

这样,您的应用程序的其余部分已经完成了其他任务,当结果准备就绪时,您可以从结果中更改 UI。

这也是我们使用加载器来复制工作状态的原因。

我希望您开始了解 jQuery 如何利用 javaScript 的这些因素,这将有助于您开发应用程序。

【讨论】:

    【解决方案4】:

    有很多方法可以处理返回的数据。

    设置一个范围在该内联函数之外的变量并将值传递给它。

    var result;

    在回调中result = arrayData;

    您还可以调用一个函数来对结果执行其他操作。

    【讨论】:

    • 我已经尝试过您的建议,但无法成功;我试过result = arrayData;callback(result = arrayData;)
    猜你喜欢
    • 2016-12-22
    • 1970-01-01
    • 1970-01-01
    • 2012-02-13
    • 1970-01-01
    • 2014-05-04
    • 2014-06-24
    • 2014-12-21
    • 1970-01-01
    相关资源
    最近更新 更多