0

我正在玩 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

4 回答 4

3

这段代码:

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

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

PS 当您说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

于 2011-09-02T02:07:43.203 回答
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并以上述结果作为参数调用它。

当浏览器看到:

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

它确实:

  1. 创建一个函数对象,调用is_it_complete(arg1, arg2)
  2. 获取函数do_something并使用上述对象作为参数调用它。

编辑 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);});
于 2011-09-02T02:16:01.473 回答
1

这两个例子都不起作用。(给审稿人的提示:这是他所说的最后两行。)

在您的第一个示例中,您调用alert(),这会引发警报对话框,甚至在get_each_total()调用该函数之前。 Javascript 调用它,显示警报(并给出发生的错觉),并将alert()调用的结果传递给get_each_total()(并在以下函数中对警报执行相同的操作)。结果为空。如果曾经调用过回调,则会引发错误。

在第二个示例中,您要声明一个函数并将对它的引用传递给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()子句永远不会被调用,因此他永远不会看到错误处理。第一个示例中警报的即时性继续给人一种发生了某些事情的错觉。

于 2011-09-02T02:10:52.990 回答
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 个“return”语句。在方法中遇到的第一个“return”将返回它的值并退出该方法;从而导致第二个“return”语句永远不会被执行。因此,在这两种方法中对“$.when.apply”的调用将永远不会被执行。

于 2011-09-02T02:53:49.987 回答