美文网首页javascript
JavaScript EventLoop

JavaScript EventLoop

作者: 技术与健康 | 来源:发表于2018-01-21 17:20 被阅读41次

    关于浏览器失去响应,之前我们介绍过


    image.png

    想象下,比如浏览器在运行一个复杂的图像转换算法,因为是单线程的,所以此时浏览器进程被阻塞了,不能进行界面渲染,也不能运行其他代码,你的应用界面会失去和用户的交互。

    这一般情况下还不会有大问题,但是当浏览器在同时运行多个类似的算法时,这个问题就很严重了。

    有一定经验js开发人员大多都理解代码的异步执行,特别是ajax的使用。

    // ajax(..) is some arbitrary Ajax function given by a library
    var response = ajax('https://example.com/api');
    
    console.log(response);
    // `response` won't have the response
    

    这里response 将不会得到你想要的结果。

    而是需要像相面这样,通过 callback函数的方式,获取结果

    ajax('https://example.com/api', function(response) {
        console.log(response); // `response` is now available
    });
    

    另外这里面提醒一下,下面的代码, async: false永远都不是一个好主意。

    // This is assuming that you're using jQuery
    jQuery.ajax({
        url: 'https://api.example.com/endpoint',
        success: function(response) {
            // This is your callback.
        },
        async: false // And this is a terrible idea
    });
    

    通过上面的例子,我们应该理解通过 异步 函数,可以帮助我们解决 类似浏览器阻塞问题。

    当然还可以通过 setTimeout(callback, milliseconds)实现同样的逻辑。如果你理解了异步,下面代码执行会输出什么呢?

    function first() {
        console.log('first');
    }
    function second() {
        console.log('second');
    }
    function third() {
        console.log('third');
    }
    first();
    setTimeout(second, 1000); // Invoke `second` after 1000ms
    third();
    

    那个这下异步处理机制的原理是什么呢?这里就要引入我们的事件循环Event Loop了

    image.png

    Event Loop有一个简单的Job(task) - 监视Call Stack和Callback Queue。如果调用堆栈为空,它将从队列中取出第一个事件,并将其推送到调用堆栈,从而有效地运行它。

    这种迭代在事件循环中被称为Tick。每个事件只是一个函数回调。

    console.log('Hi');
    setTimeout(function cb1() { 
        console.log('cb1');
    }, 5000);
    console.log('Bye');
    

    执行这段代码,下面的调用栈清楚的演示了事件循环的处理流程。

    eventloop.gif

    请注意,setTimeout(...)不会自动将您的回调放在事件循环队列中。

    它设置了一个计时器。当计时器到期时,浏览器将你的回调放到事件循环中,以便将来的一些tick会执行。但是,队列中可能还有其他事件已经被添加了 - 您的回调将不会立即执行。

    有很多关于开始使用JavaScript中的异步代码的文章和教程,建议您使用setTimeout(callback,0)。
    现在你知道Event Loop是怎么做的,以及setTimeout是如何工作的。

    你就能更好的理解下面的代码

    console.log('Hi');
    setTimeout(function() {
        console.log('callback');
    }, 0);
    console.log('Bye');
    

    尽管等待时间设置为0 ms,但浏览器控制台中的结果如下所示:
    Hi
    Bye
    callback

    相关文章

      网友评论

        本文标题:JavaScript EventLoop

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