js执行机制

发布时间:2023年12月22日

同步任务

同步任务都在主线程上执行,形成一个执行栈,程序执行的时候,按照顺序依次执行

异步任务

异步任务是通过回调函数实现的,程序执行的时候,程序会调过某个步骤继续向下执行

事件循环

描述了计算机在执行js时候的一个状态(先去执行栈中执行同步代码,然后再执行队列中异步代码)

异步任务相关添加到任务队列中(任务队列也成为消息队列)

异步任务分类

异步任务分为宏任务和微任务两种:

微任务处理完毕后才会处理宏任务,而该异步任务被判定为宏还是微取决于官方的定义。常见分类如下:

  • 宏任务:正常的异步任务都是宏任务,最常见的就是定时器(setInterval, setImmediate, setTimeout);script(整体代码) 、用户交互、IO任务;

  • 微任务:微任务出现比较晚,queueMicrotask、Promise的then和catch方法、catch、finally?

微任务生成方法:

Promise:Promise是一种异步编程的解决方案,它可以将异步操作封装成一个Promise对象,通过then方法注册回调函数,当promise变为resolve或者reject会将回调函数加入微任务队列中。

MutationObserver:MutationObserver是一种可以观察DOM变化的API,通过监听DOM变化事件并注册回调函数,将回调函数加入微任务队列中。

process.nextTick:process.nextTick是Node.js中的一个API,它可以将一个回调函数加入微任务队列中。

宏任务生成方法:

用户交互:用户在页面上进行交互操作(例如点击、滚动、输入等),会触发浏览器产生宏任务来响应用户操作。

网络请求:当浏览器发起网络请求(例如通过?Ajax、Fetch、WebSocket?等方式)时,会产生宏任务来处理请求和响应。

定时器:通过?JavaScript?宿主环境提供的定时器函数(例如?setTimeout、setInterval)可以设置一定的时间后产生宏任务执行对应的回调函数。

DOM?变化:当?DOM?元素发生变化时(例如节点的添加、删除、属性的修改等),会产生宏任务来更新页面。
跨窗口通信:在浏览器中,跨窗口通信(例如通过?postMessage?实现)会产生宏任务来处理通信消息。

JavaScript?脚本执行事件;比如页面引入的?script?就是一个宏任务。

执行顺序代码演示

setTimeout(function(){
  console.log(777)
},10)
console.log('000');//第一步

(async ()=>{
  console.log(111);//2
  await console.log(222);//3,此行执行,当await右边跟随的代码执行完毕的时候,才会执行后面的代码,此时后面的代码(后面3行)也可以算作“内部的微任务”,所以此行执行后执行输出333
  await fn()
  console.log(444);
  console.log(555);
})().then(()=>{
  console.log(666);
});
function fn(){
  console.log('a')
  return new Promise((res,rej)=>{
    console.log('b')
    res('d')
    console.log('c')
  })
}
console.log('333');//4

输出:

注意:

promise内部遇到resolve()和reject()调用的时候,会继续执行后面的代码,但是then和reject就直接放入为微任务队列中,等待同步任务执行

但async内部遇到await的时候,只有当await右边跟随的代码执行完毕的时候,才会执行后面的代码,此时后面的代码也可以算作内部的微任务(因为遇到await会将等await执行完成后,执行外面的同步任务,再执行await后面的任务,见下图)

setTimeout(function(){
  console.log(777)
},10)
console.log('000');//第一步

(async ()=>{
  console.log(111);//2
  await console.log(222);   //3,此行执行,当await右边跟随的代码执行完毕的时候,才会执行后面的代码,此时后面的代码(237-239行)也可以算作内部的微任务,所以此行执行后执行252行
  await fn()
  console.log(444);
  console.log(555);
})().then(()=>{
  console.log(666);
});
async function fn(a){
  console.log(a+'a')
  await console.log(222222)
  return new Promise((res,rej)=>{
    console.log(a+'b')
    res(a+'d')
    console.log(a+'c')
  })
}
fn(1).then((e)=>{
  console.log(e);
})
console.log('333');

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