使用Ajax回调的Javascript线程

使用Ajax回调的Javascript线程,javascript,Javascript,给定以下代码: <textarea id="mytext"></textarea> 第一次警报会出现吗 第二次警报会出现吗 为什么? javascript不是多线程的,因此,如果两个if语句中的两个密码都为true,则两个警报都将按该顺序显示。javascript不是多线程的,因此,如果两个if语句中的两个密码都为true,则两个警报都将按该顺序显示。除了WebWorkers,JavaScript在单个线程中运行,因此即使用户按键、单击元素或与页面执行任何其他交互,从J

给定以下代码:

<textarea id="mytext"></textarea>
  • 第一次警报会出现吗
  • 第二次警报会出现吗
  • 为什么?

  • javascript不是多线程的,因此,如果两个if语句中的两个密码都为true,则两个警报都将按该顺序显示。

    javascript不是多线程的,因此,如果两个if语句中的两个密码都为true,则两个警报都将按该顺序显示。

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

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

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

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


    另外,一个小的打字错误(
    $(“#mytext”).val().length()
    而不是
    $(“#mytext”).val()
    )将导致程序崩溃。

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

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

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

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


    另外,一个小的打字错误(
    $(“#mytext”).val().length()
    而不是
    $(“#mytext”).val()
    )会导致程序崩溃。

    对于1和2的答案…试试看?对于1和2的答案…试试看?使用worker可以获得线程,但在他的例子中,我相信你是正确的。即使使用worker,您不会遇到多线程问题,workers/main之间所能做的就是消息传递。使用workers可以获得线程,但在他的示例中,我相信您是正确的。即使使用workers,您也不会遇到多线程问题,workers/main之间所能做的就是消息传递。因此,如果用户在长度处理期间在textarea中键入,$(“#mytext”).val()将不会更改,直到整个回调方法完成?没错,漫长的处理将冻结整个UI,因此textarea将不会收到用户的按键(因此,您的keydown处理程序将不会运行,按下的键甚至不会显示在文本区域中)。在所有JS完成后,如果用户尝试键入,并且浏览器已将所有内容排队,则用户可能会看到出现一连串的键。因此,如果用户在长度处理期间在文本区域中键入,$(“#mytext”).val()在整个回调方法完成之前不会更改?没错,冗长的处理将冻结整个UI,因此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();
        });
    }