使用Ajax回调的Javascript线程

时间:2010-12-05 04:13:37

标签: javascript

给出以下代码:

<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();
    });
}
  1. 第一个警报会显示吗?
  2. 第二次警报会显示吗?
  3. 为什么?

2 个答案:

答案 0 :(得分:3)

除了WebWorkers之外,JavaScript在单个线程中运行,因此即使按下键,单击元素或执行与页面的任何其他交互,JS可访问的数据也不会更改。事实上,UI将阻塞,直到你的JS完成运行;只有在解释器运行了所有JavaScript代码之后,它才会放弃对浏览器的控制,浏览器最终可以处理排队的所有UI事件。

因此,假设您的“冗长处理”不会修改storedVal第一个警告永远不会显示。用户或浏览器没有机会让JS解释器修改storedVal

第二个警告也永远不会显示,假设没有其他JS代码可以修改storeVal或textarea的值。在更复杂的场景中仍然如此,在发出AJAX请求之后但在调用回调函数之前,用户在文本框中键入:

  1. 用户键入textarea,调用onkeydown处理程序,在storedVal中保存textarea的值,然后发送AJAX请求。 JS解释器将控制权交给浏览器。
  2. AJAX请求正在进行中,用户在textarea中输入,导致浏览器第二次调用onkeydown处理程序,从而用textarea的新值覆盖storedVal并发出另一个AJAX请求。
  3. 当第一个AJAX响应到达并调用AJAX回调时,它会将storedVal的新值与textarea的新值进行比较,这将是相等的。
  4. 这里的关键是,如果修改$('#mytext').val()的唯一方法是键入一个键,并且修改storedVal的唯一代码是storedVal = $('#mytext').val(),那么这两个将永远是等于你的AJAX回调内部。

    P.S。一个小错字($('#mytext').val().length()而不是$('#mytext').val())会导致程序崩溃。

答案 1 :(得分:1)

javascript不是多线程的,因此,如果两个ifs语句中的两个条件都为真,则两个警报都将按此顺序显示。