zoukankan      html  css  js  c++  java
  • javascript事件循环

    -

    javascript事件循环机制从何而来(产生原因):

    因为javascript是单线程的,javascript自上而下执行,但是不一定都是同步代码,中间会遇到一些异步的代码,比如定时器。那么这时候,单线程的javascript该如何应对呢?

    于是就想了个解决办法,用事件循环(event loop)来应对异步。

    补充:为什么javascript会被设计成单线程?

    假如说。javascript是多线程的,有两个线程同时去操作一个DOM,期中一个对这个DOM加一个属性,而另一线程要删除这个DOM,那么以哪个线程为准呢?这样就会产生许多复杂的问题要处理,

    所以就设计成单线程最合理。虽然h5,提出了web worker新标准,但是它受主线程限制,它是主线程的一个子线程。

    下面来说一下javascript 事件循环机制(event loop)

    1、执行栈

    2、事件队列(任务队列)

      任务又分为宏任务和微任务

    事件队列: 异步代码的执行,遇到异步事件不会等待它返回结果,而是将这个事件挂起,继续执行执行栈中的其他任务。当异步事件返回结果,将它放到事件队列中,被放入事件队列不会立刻执行起回调,而是等待当前执行栈中所有任务都执行完毕,主线程空闲状态,主线程会去查找事件队列中是否有任务,如果有,则取出排在第一位的事件,并把这个事件对应的回调放到执行栈中,然后执行其中的同步代码。

    主线程会依次执行执行栈内的代码,遇到异步代码(宏任务|微任务),就会将它们放到事件队列中(任务队列中),如果是宏任务,就放在宏任务队列,如果是微任务,就放在微任务队列。

    如果主执行栈执行完毕,会从事件队列中去取事件,放在执行栈中执行。

    事件队列遵守先进先出原则。

    先执行宏任务,如果本次宏任务执行产生了微任务,会先把这个微任务执行完,再执行下一个宏任务

    宏任务有哪些?

    • script(整体代码)
    • setTimeout()
    • setInterval()
    • postMessage
    • I/O
    • UI交互事件

    微任务有哪些?

    • new Promise().then(回调)
    • MutationObserver(html5 新特性)

    简单总结一下顺序

    执行宏任务,然后执行该宏任务产生的微任务,若微任务在执行过程中产生了新的微任务,则继续执行微任务,微任务执行完毕后,再回到宏任务中进行下一轮循环。

    练习一道题:

    console.log('start')
    
    setTimeout(function() {
      console.log('setTimeout')
    }, 0)
    
    Promise.resolve().then(function() {
      console.log('promise1')
    }).then(function() {
      console.log('promise2')
    })
    
    console.log('end')

    执行顺序:

    1、全局代码压入执行栈执行,输出 start

    2、setTimeout压入 macrotask队列,promise.then 回调放入 microtask队列,最后执行 console.log('end'),输出 end

    3、调用栈中的代码执行完成(全局代码属于宏任务),接下来开始执行微任务队列中的代码,执行promise回调,输出 promise1, promise回调函数默认返回 undefined, promise状态变成 fulfilled ,触发接下来的 then回调,继续压入 microtask队列,此时产生了新的微任务,会接着把当前的微任务队列执行完,此时执行第二个 promise.then回调,输出 promise2

    4、此时,microtask队列 已清空,接下来会会执行 UI渲染工作(如果有的话),然后开始下一轮 event loop, 执行 setTimeout的回调,输出 setTimeout

    最后输出结果:

    • start
    • end
    • promise1
    • promise2
    • setTimeout

    -

  • 相关阅读:
    在这个互联网泡沫时代,施主你有何焦虑?
    对于公司最近一次技术分享的总结
    Windows系统下Redis的安装
    论语
    系统的简单和复杂是由什么决定的?
    Swift之 ? 和 !
    div模拟table,可实现左右高度同增长(html布局)
    动态添加的无缝轮播
    根据数据库名获取表和字段信息(mysql版)
    博客园更新了?
  • 原文地址:https://www.cnblogs.com/fqh123/p/15255338.html
Copyright © 2011-2022 走看看