Javascript Threading With Ajax Callbacks
Given the following code:
<textarea id="mytext"></textarea>
...
var storedVal = "";
function taChanged(evt) {
storedVal = $("#mytext").val();
}
$(document).ready(function() {
$("#mytext").onkeydown(taChanged);
doUpdate();
});
function doUpdate() {
$.ajax("example.com/updates", function() {
var storedVal1 = storedVal ;
// lengthy processing here
// ........
var storedVal2 = storedVal 开发者_开发技巧;
var domVal = $("#mytext").val();
if(storedVal1 != storedVal2) alert("storedVal changed while processing");
if(storedVal1 != domVal) alert("real val changed while processing");
doUpdate();
});
}
- Will the first alert ever show?
- Will the second alert ever show?
- Why?
Aside from WebWorkers, JavaScript runs in a single thread so even if the presses a key, clicks on an element, or performs any other interaction with the page, the data accessible from JS will not change. In fact, the UI will block until your JS finishes running; only after the interpreter has run all of your JavaScript code does it relinquish control to the browser, which can finally process all of the UI events that have queued up.
Therefore, assuming that your "lengthy processing" does not modify storedVal
, the first alert can never show. There is no opportunity for the user or browser to get the JS interpreter to modify storedVal
.
The second alert can never show as well, assuming that there is no other JS code that modifies storeVal
or the textarea's value. This remains true in more complex scenarios, where the user types in the textbox after you issue your AJAX request but before the callback function is invoked:
- The user types in the textarea, your
onkeydown
handler is invoked, you save the value of the textarea instoredVal
, and then send an AJAX request. The JS interpreter gives back control to the browser. - The AJAX request is in flight, and the user types in the textarea, causing the browser to invoke the
onkeydown
handler a second time, thus overwritingstoredVal
with the new value of the textarea and issuing another AJAX request. - When the first AJAX response arrives and invokes the AJAX callback, it will compare the new value of
storedVal
with the new value of the textarea, which will be equal.
The key here is that if the only way to modify $('#mytext').val()
is by typing a key, and if the only code that modifies storedVal
is storedVal = $('#mytext').val()
, then the two will always be equal inside of your AJAX callback.
P.S. A small typo ($('#mytext').val().length()
instead of $('#mytext').val()
) will cause the program to crash.
javascript is not multi threaded, so, if both coditions in both if's statements are true, both alert will show, in that order.
精彩评论