Can you explain why this jQuery code works?
I know that it works. I have implemented it successfully.
$("#vehicle_application_product_id").autocomplete({
minLength: 2,
source: function(request, response) {
var term = request.term;
if (开发者_运维百科term in cache) {
response(cache[term]);
return;
}
lastXhr = $.getJSON("/products/get_json_list", request, function(data, status, xhr) {
cache[term] = data;
if (xhr === lastXhr) {
response(data);
}
});
}
});
I am like a script kiddie with some of this stuff. I would NEVER be able to write that anonymous function myself, because of the following reasons:
1) How did this person know to put the parameters "request" and "response" in the spec?
2) The lines beginning "lastXhr = " is really mystifying. There is yet another anonymous function at the end. I realize that is probably a callback, something that is executed after the request is sent to the specified URL.
3) That last conditional in the anonymous function:
if ( xhr === lastXhr ) {
response( data );
}
What the heck is that? If then third parameter, xhr, from this anonymous block is equal to the vaue returned by the .getJSON call ENCOMPASSING this anonymous block, return the data in the response?
That is really the most difficult part to wrap my head around. And I notice that's 3 equals signs. This looks like pretty advanced code concepts, I would just appreciate what the rationale behind this is so that I can become a better coder.
The parameters
request
andresponse
will be passed to the function assigned to thesource
option as documented here. In essence, the plugin promises to pass these two parameters to the callback and that's how you signal that you do want to get hold of them.That function is a callback scheduled to be invoked when the request completes, not after it's simply sent. Also, when calling
getJSON
, the code assigns the resulting object to thelastXhr
variable so that it remembers which was the last request that it made.Inside the callback, you have a reference to the request that completed in the form of the parameter
xhr
. So thatif
is equivalent to writing:if (the request that completed is the last request made) { // ... }
Why do this? To make sure that you do not act on the results of the request if, due to the response taking too long to come back and the user typing too fast, you have multiple outstanding requests. In such a scenario, you are really not interested in the results of any but the last one you made.
How does the callback have access to the variable
lastXhr
from an outer scope? This is due to closure.What's with the three equal signs? That's the identity operator.
1) They read the documentation for the jQuery UI Autocomplete plugin here: http://jqueryui.com/demos/autocomplete/#option-source
2) The usage seen with lastXhr
is similar to those shown the jQuery documentation page for getJSON: http://api.jquery.com/jQuery.getJSON/
3) The person writing the code likely wanted jQuery autocomplete to only show the results of the most recent $.getJSON()
request for autocomplete data. For example, say I type "abc" and autocomplete fires but then I type "d" so it's "abcd" now -- then another autocomplete fires. We only care about the results for "abcd", right? So this check that lastXhr
matches the current xhr
does that!
Note that ===
in JavaScript is testing that the objects are of the same type and are equal. In JS, 1 == '1'
is true but 1 === '1'
is not. I highly recommend "JavaScript: The Good Parts" which goes into the concepts of closure and other interesting facets of the language.
精彩评论