美文网首页
JS异步编程(一):单线程模型

JS异步编程(一):单线程模型

作者: ifcode | 来源:发表于2014-04-26 21:56 被阅读543次

    随着对JS的深入,异步编程是每个JS程序员都跳不过的话题。不仅在前端开发有大量的异步事件处理,NODE更是有出了名的callback hell。为了更好地掌握JS异步编程,让我们从基础开始看起吧。

    先看一个简单的例子:

    for (var i = 1; i <= 3; i++) {
        setTimeout(function() { console.log(i); }, 0);
    }
    

    若是从C、JAVA转来的程序员,第一直觉是setTimeout延时为0,因此程序应该打印1,2,3。但是程序执行的结果却是4,4,4。

    再看下面一个列子:

    var start = new Date;
    setTimeout(function(){
        var end = new Date;
        console.log('Time elapsed:', end - start, 'ms');
    }, 500);
    while (new Date - start < 1000) {};
    

    SetTimeout设置了500ms的延迟,而随后的while则空循环等待1000ms。直觉的反应是console会打印500,但执行的结果却是出乎意料的约等于1000。

    这里充分说明了一个问题:setTimeout没有调用另一个线程,JS程序的执行是基于单线程模型的。于是当调用setTimeout的时候,这个延时事件便会排入事件队列。而线程继续执行后续的代码,直到代码全部执行完毕之后才来处理事件队列中的事件。

    处理用户输入时也是类似的情况,当用户点击一个附加了事件处理函数的对象时,这个点击事件就排入事件队列。但该事件并不会被立即处理,而是要等到当前代码全部运行结束后才会被处理。

    小结:JS是单线程执行的,JS代码永远不会被中断,所有的事件都会被排入事件队列,直到代码执行完毕后才会处理这些事件。

    P.S: webkit的console.log也是异步的,在浏览器中执行:

    var obj = {};
    console.log(obj);
    obj.foo = 'bar';
    

    console并没有立即打印空对象,而是等到代码返回到事件队列的时候才打印对象,此时打印是对象{foo:bar}。

    与此相反,NODE中console是同步的,将会立即打印{}。

    相关文章

      网友评论

          本文标题:JS异步编程(一):单线程模型

          本文链接:https://www.haomeiwen.com/subject/zxcrtttx.html