zoukankan      html  css  js  c++  java
  • 浅谈js事件循环机制

    太多关于js事件循环机制的面试问题了,必须要好好看一眼小小的总结一波;于是查了很多资料,看了很多相关文档;

    得出以下姿势;先来张图解释下

    <!DOCTYPE html>
    <html>
        <head>
            <meta charset="utf-8">
            <title></title>
        </head>
        <body>
            <div id="root">
                <h1>JS事件的循环</h1>
                <h3>参考阮一峰大神:http://www.ruanyifeng.com/blog/2014/10/event-loop.html</h3>
                <p>同步任务:指的是,在主线程上排队执行的任务,只有前一个任务执行完毕,才能执行后一个任务;</p>
                <p>异步任务:指的是,不进入主线程、而进入"任务队列"(task queue)的任务,只有"任务队列"通知主线程,某个异步任务可以执行了,该任务才会进入主线程执行。</p>
                <p>异步执行的运行机制如下:(同步执行也是如此,因为它可以被视为没有异步任务的异步执行。)</p>
                <p>(1)所有同步任务都在主线程上执行,形成一个执行栈(execution context stack)。</p>
                <p>(2)主线程之外,还存在一个"任务队列"(task queue)。只要异步任务有了运行结果,就在"任务队列"之中放置一个事件。</p>
                <p>(3)一旦"执行栈"中的所有同步任务执行完毕,系统就会读取"任务队列",看看里面有哪些事件。那些对应的异步任务,于是结束等待状态,进入执行栈,开始执行。</p>
                <p>(4)主线程不断重复上面的第三步。只要主线程空了,就会去读取"任务队列"【事件的队列 or 消息的队列】,这就是JavaScript的运行机制。这个过程会不断重复</p>
                <p>process.nextTick和setImmediate的一个重要区别:多个process.nextTick语句总是在当前"执行栈"一次执行完,多个setImmediate可能则需要多次loop才能执行完</p>
                <p>
                    宏任务(macrotask):script(整体代码)、setTimeout、setInterval、UI 渲染、 I/O、postMessage、 MessageChannel、setImmediate(Node.js 环境)
                    微任务(microtask):Promise、 MutaionObserver、process.nextTick(Node.js环境)
                </p>
                <p>
                    同步代码:代码单线执行,发送服务器请求后,等待返回数据,会出现网页空白(阻塞网页运行) 如alert for循环
                    异步代码:代码发送请求后继续执行后续代码,不等待服务器返回数据(网页运行流畅)
                    js中常见的异步执行代码:
                    1.ajax请求:异步 JavaScript 和 XML
                    2.定时器、setTimeout:间隔一段时间才会执行,
                    3.事件处理函数:满足事件触发条件才会执行
                </p>
            </div>
            <script type="text/javascript">
                // 遇到【同步任务】直接执行,遇到【异步任务】分类为宏任务(macro-task)和微任务(micro-task)。
                // 宏任务:整体的Script setTimeout setInterval
                // 微任务:Promise process.nextTick
                // 所谓"回调函数"(callback),就是那些会被主线程挂起来的代码。异步任务必须指定回调函数,当主线程开始执行异步任务,就是执行对应的回调函数
                // 任务队列是一个先进先出的数据结构
                // 主线程从"任务队列"中读取事件,这个过程是循环不断的,所以整个的这种运行机制又称为Event Loop(事件循环)
                console.log('script start');
                
                setTimeout(function () {
                  console.log('setTimeout');
                }, 0);
                
                Promise.resolve()
                  .then(function () {
                    console.log('promise1');
                  })
                  .then(function () {
                    console.log('promise2');
                  });
                
                console.log('script end');
                // 依次输出结果
                // script start -> script end -> promise1 -> promise2 -> setTimeout
                
                // for (let i = 0; i < 99999; i++) {
                //     console.log("我在执行 但用户不知道")
                // }
                // console.log("循环完毕才可以打印")
                
                /*****************同步代码异步代码有趣的打印****************/
                for (var i = 0; i < 10; i++) {
                    setTimeout(function() {
                        console.log(i,'输出十次10')
                    }, 0)
                }
                    
                // 立刻执行函数
                for (var i = 0; i < 10; i++) {
                    (function(i){   
                        setTimeout(function (){
                          console.log(i, '输出0-9'); 
                         },1000); 
                    })(i); 
                }
    
                for (let i = 0; i < 10; i++) {
                    setTimeout(function() {
                        console.log(i,'输出0-9')
                    }, 0)
                }
                
                /*
                结论:
                 有微则微,无微则宏 【如果微任务列表里面有任务,会执行完毕后在执行宏任务】
                 关于promise或者es语法参考:https://es6.ruanyifeng.com/#docs/promise
                */
            </script>
        </body>
    </html>

    鄙人才疏学浅,如有不对请指出!!!转载注明出处!!!谢谢合作!!!

  • 相关阅读:
    新概念英语第四册16-30课(转)
    新概念英语第四册01-15课(转)
    通过了解MySpace的六次重构经历,来认识分布式系统到底该如何创建(转载)
    BASE64编码规则及C#实现
    Lucene资料汇总
    SQL Server性能监控
    Fedex接口和测试账户
    css语法
    POI操作Excel常用方法总结 (转)
    java eclipse中的代码联动提示功能
  • 原文地址:https://www.cnblogs.com/lhl66/p/14374338.html
Copyright © 2011-2022 走看看