Jquery deferred call back oddness

↘锁芯ラ 提交于 2020-01-17 02:53:15

问题


I was playing around with call backs and deferred functions in jQuery and was wondering if anyone could tell me why this works

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"));
});

and this does not

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")});
});

as you can see the only difference is in the last two lines, where an anonymous function wraps the callback. Any insight would be nice.


回答1:


This piece of code:

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

exits out of your function. The callback is never called.

P.S. When you're saying the only difference is an anonymous function wrapping the callback, you imply that you're also passing a function in the first version of your code. That is not true; you're trying to pass in whatever alert('whatever'); is returning, which is undefined!

Further explanation:

Both of your functions (get_each_total, & get_each_total_broken) expect the parameter to be a function. This is evident by you trying to call it as a function later on in your code (callback()). However, this line:

get_each_total(alert("success"));

does not pass a function to get_each_total. It is equivalent to the following:

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

So, basically, you're not passing anything into your get_each_total function. You get a success alert right away, before get_each_total has been called.




回答2:


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

here you have the function (){ alert .... that returns a function object

 get_each_total(alert("success"));

here alert("success") is an object of whatever type alert() returns and it is not a function.

Edit:- in respone to the comment i'm going to further clarify.

when the browser sees

do_something(is_it_complete(arg1, arg2));

it goes throught the following steps:

  1. Get the function is_it_complete and call it arguments arg1 and arg2.
  2. get the function do_something and call it with the result of the above as an argument.

When the browser sees:

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

it does:

  1. Create a function object that calls is_it_complete(arg1, arg2)
  2. Get the function do_something and call it with the above object as an argument.

Edit 3:- Ok so in the first one it called the alert before running your code so it appeared to work.

you have:

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

the second return is never reached.

Edit:- thought i would put a few tips after reading the code:

var requests;
requests = [];

is redundant change that style to

var requests = [];
var url = " ....";

When you do not pass any arguments to a callback do no wrap it.

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

it is the same as:

.then(callback);

and as mentioned in the comments your url

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

Should be

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

or even:

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



回答3:


Neither example works. (Hint to reviewers: it is the last two lines of which he speaks.)

In your first example, you call alert(), which raises the alert dialog, even before the get_each_total() function is called. Javascript invokes it, showing the alert (and giving the illusion than something happened), and passes the result of the alert() call to get_each_total() (and does the same with the alert in the following function, too). The result is null. If the callback were ever called, this would raise an error.

In the second example, you're declaring a function and passing a reference to it to get_each_total(), which can then be called via your callback() expression. A function is something that responds to the () operator, meaning "do this." It would actually do something (show the alert) if your code succeeded.

But your code does not. Going to the fiddle, and looking at the console, I see this message: "Failed to load resource: the server responded with a status of 500 (Internal Server Error)." getJSON() never triggers the callback because it never succeeds.

[EDIT] @austinbv pointed out to me that I'd missed something. The 500 code is a deliberate test on his part. But his code is still broken in get_each_total_broken(); there is a misplaced return in the line

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

This returns immediately from get_each_total_broken. The when().then() clause is never invoked, so he never sees the error handling. The immediacy of the alerts in the first example continues to give the illusion that something happened.




回答4:


There are 2 problems with your code:

1) In the last two lines of code: The first example is passing the result of an execution of the "alert" method to both the "get_each_total" and "get_each_total_broken" methods. The second example is passing a function that when executed will call "alert". The second example is the correct method to perform.

For Example:

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) You have 2 "return" statements in both your methods. The first "return" encountered within a method will return it's value and exit the method; thus resulting in the second "return" statement to never be executed. Consiquentially, the call to "$.when.apply" in both methods will never, ever get executed.



来源:https://stackoverflow.com/questions/7278511/jquery-deferred-call-back-oddness

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!