zoukankan      html  css  js  c++  java
  • JS中的执行机制(setTimeout、setInterval、promise、宏任务、微任务)

    1、执行机制

    JS 是单线程的,处理 JS 任务(程序)只能一个一个顺序执行,所以 JS 中就把任务分为了同步任务和异步任务。同步的进入主线程先执行,异步的进入Event Table并注册函数,当指定的事情完成时,Event Table会将这个函数移入事件队列Event Queue,等待主线程内的任务执行完毕,然后就会从事件队列 Event Queue 中读取对应的函数,进入主线程执行。

    除了广义的同步任务和异步任务,JS 对任务还有更精细的定义:

    • macro-task(宏任务):包括整体代码script,setTimeout,setInterval,setImmediate ,I/O ,UI rendering
    • micro-task(微任务):Promise,process.nextTick,MutationObserver

    微任务先于宏任务执行(除了一开始的整体代码 script)。执行过程中,不同类型的任务会进入对应的事件队列Event Queue,比如setTimeoutsetInterval会进入相同的Event Queue。

    1.1、执行优先级

    • 同步代码执行顺序优先级高于异步代码执行顺序优先级

    (注意:process.nextTick 是 node 中的方法,而在浏览器中执行时(比如在vue项目中),会退化成setTimeout,所以在浏览器中 process.nextTick 会比 Promise.then() 慢)

    1.2、总结

    总得来说,在 JS 中,先是执行整体的同步任务代码,遇到微任务就会将其放在微任务事件队列,遇到宏任务就会放在宏任务事件队列中。

    然后整体的同步任务代码执行完后,就会先执行微任务队列中的任务,等待微任务队列中的所有任务执行完毕后,此时才会从宏任务队列中找到第一个任务进行执行。该任务执行过程中,如果遇到微任务就会放到微任务队列中,等到该任务执行完后,就会查看微任务队列中有没有微任务,如果有就先执行完微队列中的任务,否则执行第二个宏任务。以此类推。

    例如:

    console.log('script start')
    
    async function async1() {
      await async2()
      console.log('async1 end')
    }
    async function async2() {
      console.log('async2 end')
    }
    async1()
    
    setTimeout(function() {
      console.log('setTimeout')
    }, 0)
    
    new Promise(resolve => {
      console.log('Promise')
      resolve()
    })
      .then(function() {
        console.log('promise1')
      })
      .then(function() {
        console.log('promise2')
      })
    
    console.log('script end')
    

     打印顺序为:

    script start => async2 end => Promise => script end => async1 end => promise1 => promise2 => setTimeout

    首先先来解释下上述代码的 async 和 await 的执行顺序。当我们调用 async1 函数时,会马上输出 async2 end,并且函数返回一个 Promise,接下来在遇到 await的时候会就让出线程开始执行 async1 外的代码,所以我们完全可以把 await 看成是让出线程的标志。

    然后当同步代码全部执行完毕以后,就会去执行所有的异步代码,那么又会回到 await 的位置执行返回的 Promise 的 resolve 函数,这又会把 resolve 丢到微任务队列中,接下来去执行 then 中的回调,当两个 then 中的回调全部执行完毕以后,又会回到 await 的位置处理返回值,这时候你可以看成是 Promise.resolve(返回值).then(),然后 await 后的代码全部被包裹进了 then 的回调中,所以 console.log('async1 end') 会优先执行于 setTimeout

    部分参考于:https://www.cnblogs.com/wenxuehai/p/12030199.html

  • 相关阅读:
    CSS 实现图片灰度效果
    有关楼层滚动且对应楼层Nav导航高亮显示
    本地上传图片预览效果
    gulp.js 的安装以及使用
    ReactJS -- 初学入门
    ie8下jquery改变PNG的opacity出现黑边
    数据库操作 (4-3)
    Python之协程 (4-2)
    python 之 线程 3-29
    Python之 并发编程(3-19)
  • 原文地址:https://www.cnblogs.com/anu0823/p/13856832.html
Copyright © 2011-2022 走看看