js执行机制
2023-12-22 10:46:33
同步任务
同步任务都在主线程上执行,形成一个执行栈,程序执行的时候,按照顺序依次执行
异步任务
异步任务是通过回调函数实现的,程序执行的时候,程序会调过某个步骤继续向下执行
事件循环
描述了计算机在执行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
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!