api.jquery.com
api.jquery.com copied to clipboard
$.ajax() documentation should be fixed in a case where script isn't necessarily executed yet
$.getScript() returns a jqXHR object that may be used as so:
$.getScript( '/foobar.js' ).done( function ( script, textStatus ) {
// script has been loaded and executed
} );
However, it can also be provided a second, optional success argument:
$.getScript( '/foobar.js', function ( data, textStatus, jqXHR ) {
// script has been loaded, but not necessarily executed yet
} );
Notice in the second snippet that the script isn't necessarily executed yet.
This subtle, but important, difference is noted in the $.getScript() documentation:
The callback is fired once the script has been loaded but not necessarily executed.
However, $.getScript() is just a shorthand method that calls $.ajax(), and the latter seems to have a mistake in its documentation:
If
scriptis specified,$.ajax()will execute the JavaScript that is received from the server before passing it on to the success handler as a string.
To summarize, if I correctly figured out the behavior of $.ajax(), the remote script has been executed when using the returned jqXHR object, but not necessarily when using the callbacks (success, complete, etc.) passed to the settings argument.
Thus, the above line from the documentation should be fixed. You may also want to emphasize these two different behaviors.
Thanks for the report. To be honest, I don't see a case where the callback could be fired before the script is executed. Maybe that's an artifact of older implementation?
@vlakoff do you know a case where this can happen?
It seems that, indeed, users should expect the script to be loaded and executed with both codes. (it might break someone's workflow, but I doubt so.)
This had been discussed on this topic, about loading scripts on MediaWiki. The desired behaviour is, again, to load and execute a script before executing a given callback. It had been pinpointed that the second syntax, while it seems to be an innocent shorthand, might have a different behaviour actually.
Though, I just tried to reproduce that "script is loaded but not executed" behaviour, without success. When the callback is reached, the script has been executed already. I can't say if it works this way only by luck (i.e. it works at most times but is not enforced), or if the behaviour is this one actually.
I see this wording was added in https://github.com/jquery/api.jquery.com/pull/133 with little discussion. Perhaps it was inaccurate from the start.
This could have possibly been the behavior in some old browsers, it's hard to check that right now. I think we can update the entry to say the callback fires after execution. Let me migrate that to a docs issue.
PRs to update the docs are welcome!
Nowadays, with the second syntax from OP, internally the success argument is attached as a done() handler to the jqXHR instance; see ajax.js#L670.
That's the same jqXHR instance that gets returned and attached a done() handler with the first syntax from OP.
So, both syntaxes are equivalent.
Though, we should investigate if it has always been the case. Maybe the jQuery code has been modified at some point.
I made some digging, and the complete argument gets attached to the returned jqXHR instance since these commits from late 2010 / early 2011:
-
https://github.com/jquery/jquery/commit/ab3ba4a81252c4357a7aab5f24d765d41d47986e
- expand large diffs then search for
callbacksListsin ajax.js and xhr.js - refs #7195 on bugs.jquery.com
- expand large diffs then search for
-
https://github.com/jquery/jquery/commit/6dbffb8596a9c96c68386ecc2d95da25b9dee369
-
https://github.com/jquery/jquery/commit/cbf591152c9f61381e552c9a15bb7c339f1451a9 followed by https://github.com/jquery/jquery/commit/1ca82ccd9489f11d3a8fbdd8a32b4c164ffaf483 – at this point, we now have an handler named
done()
We may also note this commit from 2015 which removed success() and kept done() method:
- https://github.com/jquery/jquery/commit/9d1b989f20b550af3590691723b0620f6914626e
To summarize, both syntaxes from OP are equivalent since the Ajax Rewrite and its new jqXHR object, introduced in jQuery 1.5, released on January 2011.
I should have missed something… how could the syntaxes be equivalent, as the callback function signatures are different (function (script, textStatus) vs function (data, textStatus, jqXHR))…
I think those signatures are also the same, documentation is just not fully up to date. script and data are the same here and jqXHR is missing in docs for one of them.
BTW, for cross-domain scripts on 3.x-stable or most scripts on the main branch (!) script or data above will be undefined - this is because we're using a script tag by default in these situations and then you don't get the script contents available in JS.
Thanks for the useful clarifications. The docs seem to be up-to-date about the supplied jqXHR third parameter; it's just omitted in the two examples here that use .done(), as they don't use this parameter.
Created PR #1209 to address the issue initially raised here.
About the script/data callback parameter that may be undefined (mentioned just above), indeed it should be documented this parameter may not be defined, depending on several conditions which are the jQuery version and the "remoteness" of the script, and that it just shouldn't be relied on. To get the script content, $.get() should be used additionally/instead. I'm leaving this documentation fix (or update, actually) to anyone willing to take it.
By the way, I think it should be rare to need the script content (and even more rare to execute a script and also need its content).