JS运行机制、Event Loop

发布时间:2024年01月04日

1、JS运行机制

? ?JS最大的特点就是单线程,所以他同一时间只能做一件事情。使单线程不阻塞,就是事件循环。

在JS当中分为两种任务:

  • 同步任务:立即执行的任务,一般放在主线程中(主执行栈)。
  • 异步任务:异步执行的任务,进入任务队列(task queue)。只有任务队列通知主线程,某个异步任务可以执行力,该任务才会进入主线程执行。

事件循环就是不断重复上面两步骤、异步与同步任务执行如下。

2、宏任务与微任务

? ? ? ? 异步任务又分为宏任务和微任务。

常见的微任务有:

  • Promise.then
  • Async/Await
  • MutationOberver
  • Object.oberver
  • process.nextTick

常见的宏任务有:

  • script(可以理解其为外层同步代码)
  • setTimeout/setInterval
  • UI
  • postMessage\MessageChannel
  • I/O
  • setImmediate

他的运行机制是:

  1. 执行一个宏任务、如果遇到微任务就将他放到微任务的队列中
  2. 执行当前宏任务后,检查微任务事件队列,将其执行完毕
  3. 循环上面的步骤如下图

3、Async/Await

? ? ?async是异步的意思,await可以裂解为async wait。所以可以理解为:

  • async:声明一个异步的方法
  • await:等待异步方法执行

Async/Await相对于Promise的优势:

  • Promise虽然拜托了地狱回调,但是他很的链式调用也会带来阅读负担
  • Async/Await是异步函数但是几乎同步的写法,非常优雅
  • Async/Await错误处理友好,可以使用成熟的try/catch
  • 调试友好,Promise由于没有代码块,不能反回表达式的箭头函数中设置断点
  1. async ,awit命令后面返回Promise对象。如果不是对象直接返回对应的值。
function f() {
    return Promise.resolve('TEST');
}

// asyncF is equivalent to f!
async function asyncF() {
    return 'TEST';
}
  1. ?不管await后面跟着是什么,await都会阻塞后面的代码
async function fn1 (){
    console.log(1)
    await fn2()
    console.log(2) // 阻塞
}

async function fn2 (){
    console.log('fn2')
}

fn1()
console.log(3)

//1,fn2,3,2

? ? ? ? ?上面例子中,await会阻塞下面的代码(即加入微任务队列),先执行async外面的同步代码,执行完毕之后回到async函数执行之前阻塞的代码。

4、流程分析

? ? ?下面一个案例可以看到时间循环机制为了达到单线程不阻塞,他的执行流程是怎么样的。

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

//script start,async1 start,async2,promise1,script end,async1 end,promise2,settimeout

?分析:

  • 执行同步任务async1、promise、console直接打印script startasync1 startasync2promise1script end
  • 遇到await、Promise.then添加到微任务队列
  • 遇到settimeout添加到宏任务队列
  • 清空微任务队列打印async1 endpromise2
  • 处理宏任务队列打印settimeout

参考文献:
javaScript运行机制 (同步与异步)的理解_js同步与异步的机制-CSDN博客

面试官:说说你对事件循环的理解 | web前端面试 - 面试官系列

文章来源:https://blog.csdn.net/qq_42794545/article/details/135391036
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。