Jquery延迟回拨奇怪

时间:2011-09-02 01:51:29

标签: jquery callback jquery-deferred

我正在玩jQuery中的回调函数和延迟函数,并且想知道是否有人能告诉我为什么会这样做

http://jsfiddle.net/austinbv/QVujr/

  get_each_total = function(callback) {
    var requests;
    requests = [];
      var url;
        url = "http://otter.topsy.com/search.js?callback=?&apikey=38A260E9D12A4908B1AF9184B691131&q=justin+bieber&window=d";
        return requests.push($.getJSON(url, function(data) {
        }));
    return $.when.apply($, requests).then(function() {
      callback();
    }, function() {
      return alert("There was an error communicating with a remote library, try again in a few");
    });
  };



  get_each_total_broken = function(callback) {
    var requests;
    requests = [];
      var url;
        url = "http://otter.topsy.com/hjhkl/sehjkhhkjhkarch.js?callback=?&apikey=38A260E9D12A4908B1AF9184B691131&q=justin+bieber&window=d";
        return requests.push($.getJSON(url, function(data) {
        }));
    return $.when.apply($, requests).then(function() {
      callback();
    }, function() {
      return alert("There was an error communicating with a remote library, try again in a few");
    });
  };

$(function () {
    get_each_total(alert("success"));
    get_each_total_broken(alert("fail"));
});

这不是

http://jsfiddle.net/austinbv/wzve6/

  get_each_total = function(callback) {
    var requests;
    requests = [];
      var url;
        url = "http://otter.topsy.com/search.js?callback=?&apikey=38A260E9D12A4908B1AF9184B691131&q=justin+bieber&window=d";
        return requests.push($.getJSON(url, function(data) {
        }));
    return $.when.apply($, requests).then(function() {
      callback();
    }, function() {
      return alert("There was an error communicating with a remote library, try again in a few");
    });
  };



  get_each_total_broken = function(callback) {
    var requests;
    requests = [];
      var url;
        url = "http://otter.topsy.com/hjhkl/sehjkhhkjhkarch.js?callback=?&apikey=38A260E9D12A4908B1AF9184B691131&q=justin+bieber&window=d";
        return requests.push($.getJSON(url, function(data) {
        }));
    return $.when.apply($, requests).then(function() {
      callback();
    }, function() {
      return alert("There was an error communicating with a remote library, try again in a few");
    });
  };

$(function () {
    get_each_total(function () { alert("success")});
    get_each_total_broken(function () {alert("fail")});
});

正如您所看到的,唯一的区别在于最后两行,其中匿名函数包装了回调。任何见解都会很好。

4 个答案:

答案 0 :(得分:3)

这段代码:

return requests.push($.getJSON(url, function(data) {
}));

退出您的功能。永远不会调用callback

P.S。当您说the only difference is an anonymous function wrapping the callback时,您暗示您也在代码的第一个版本中传递了一个函数。那不是真的;你正试图传递alert('whatever');正在返回的内容,即 undefined

进一步说明:

您的两个函数(get_each_total,& get_each_total_broken)都希望参数是一个函数。您可以稍后在代码(callback())中将其称为函数,这一点很明显。但是,这一行:

get_each_total(alert("success"));

不会将函数传递给get_each_total。它等同于以下内容:

var returnedFromAlert = alert("success");
get_each_total(returnedFromAlert);

所以,基本上,你没有将任何内容传递给你的get_each_total函数。在调用success之前,您会立即收到get_each_total提醒

答案 1 :(得分:2)

get_each_total(function () { alert("success")});

这里有function (){ alert ....返回函数对象

 get_each_total(alert("success"));

此处alert("success")alert()返回的任何类型的对象,它不是函数。

编辑: - 重新评论我将进一步澄清的评论。

当浏览器看到

do_something(is_it_complete(arg1, arg2));

它经历了以下步骤:

  1. 获取函数is_it_complete并将其称为参数arg1arg2
  2. 获取函数do_something并使用上述结果作为参数调用它。
  3. 当浏览器看到:

    do_something(function () { is_it_complete(arg1, arg2) });
    

    它确实:

    1. 创建一个调用is_it_complete(arg1, arg2)
    2. 的函数对象
    3. 获取函数do_something并以上述对象作为参数调用它。
    4. 编辑3: - 好的,所以在第一个调用警报之前,它在运行代码之前就已经开始工作了。

      你有:

      get_each_total = function(callback) {
           // ... *snip* 
          return requests.push($.getJSON(url, function(data) {}));
          return $.when.apply($, requests).then(function() {
              // ... *snip*
          });
      };
      

      永远不会达到第二次回归。

      编辑: - 以为我会在阅读完代码后提出一些提示:

      var requests;
      requests = [];
      

      是样式为

      的冗余更改
      var requests = [];
      var url = " ....";
      

      当你没有将任何参数传递给回调时,不要包装它。

      .then(function(){ callback();}) 
      

      它与:

      相同
      .then(callback);
      

      并在评论中提到你的网址

      url = "http://otter.topsy.com/hjhkl/sehjkhhkjhkarch.js?callback=?&apikey=38A260E9D12A4908B1AF9184B691131&q=justin+bieber&window=d";
      

      应该是

      url = "http://otter.topsy.com/hjhkl/sehjkhhkjhkarch.js?callback=somevalue&apikey=38A260E9D12A4908B1AF9184B691131&q=justin+bieber&window=d";
      

      甚至:

      url = "http://otter.topsy.com/hjhkl/sehjkhhkjhkarch.js"
      $.getJSON(url, {
          "callback": "somevalue",
          "apikey": "38A260E9D12A4908B1AF9184B691131",
          "q": "justin bieber",
          "window": "d"
      }, function(data){ alert("Got: " + data);});
      

答案 2 :(得分:1)

两个例子都不起作用。 (提示评论者:这是他说的最后两行。)

在第一个示例中,即使在调用alert()函数之前,也会调用get_each_total(),它会引发警告对话框 Javascript调用它,显示警报(和给出幻觉而不是发生的事情),并将alert()调用的结果传递给get_each_total()(并且对以下函数中的警报也一样)。结果为null。如果调用了回调,则会引发错误。

在第二个示例中,您声明了一个函数并将对它的引用传递给get_each_total(),然后可以通过callback()表达式调用它。函数响应()运算符,意思是“执行此操作”。如果您的代码成功,它实际上会做一些事情(显示警报)。

但是你的代码没有。转到小提琴,看着控制台,我看到这样的消息:“无法加载资源:服务器响应状态为500(内部服务器错误)。” getJSON()永远不会触发回调,因为它永远不会成功

[编辑] @austinbv向我指出我错过了什么。 500代码是他的故意测试。但他的代码仍在get_each_total_broken()中被打破;行

中有错误的return
return requests.push($.getJSON(url, function(data) {  }));

这会立即从get_each_total_broken返回。永远不会调用when().then()子句,因此他永远不会看到错误处理。第一个例子中警报的即时性继续让人觉得发生了一些事情。

答案 3 :(得分:0)

您的代码有两个问题:

1)在最后两行代码中:第一个示例是将“alert”方法的执行结果传递给“get_each_total”和“get_each_total_broken”方法。第二个例子是传递一个函数,该函数在执行时将调用“alert”。第二个例子是正确的执行方法。

例如:

function test(v) {
    // do something
    return null;
}

// executes "test" immediately and passes it's result to "someOtherFunction"
someOtherFunction(test(v));
// will pass a function to "someOtherFunction" to be executed later
someOtherFunction(function(){ test("value"); });

2)你的两种方法都有2个“返回”语句。方法中遇到的第一个“返回”将返回它的值并退出方法;从而导致第二个“返回”语句永远不会被执行。因此,两种方法中对“$ .when.apply”的调用永远不会被执行。

相关问题