前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >js运行机制同步与异步(宏任务与微任务)

js运行机制同步与异步(宏任务与微任务)

作者头像
qiangzai
发布2022-09-26 18:48:14
1.1K0
发布2022-09-26 18:48:14
举报
文章被收录于专栏:强仔博客

js运行机制

众所周知,javascript的最大特点就是单线程,同一时间追能做同一件事,所以为了防止主线程的阻塞,在代码执行时分为同步任务异步任务,所有的同步任务在主线程上执行,形成执行栈,而异步任务形成一个新的任务队列,又把任务队列中的异步任务分为宏任务微任务,虽然他们都在任务队列中,但是它们却在不同的队列中,微任务的执行优先级大于宏任务,他们的结构如图所示。

宏任务

浏览器为了能够使得JS内部任务与DOM任务能够有序的执行,会在一个任务执行结束后,在下一个任务执行开始前,对页面进行重新渲染

常见的宏任务主要有 定时器ajax读取文件dom事件setImmediate(Node.js 环境)requestAnimationFrameI/0UI交互postMessage

微任务

需要在当前 同步任务 执行结束后立即执行的任务,比如对一系列动作做出反馈,或者是需要异步的执行任务而又不需要分配一个新的任务,这样便可以减小一点性能的开销

常见的微任务包括Promise.thenObject.observeMutationObserverprocess.nextTick(Node.js 环境)

运行机制

代码案例

1.定时器因为是异步宏任务,所以先执行主线程的打印语句,主线程没有任务再从宏任务任务队列中取出定时器执行

代码语言:javascript
复制
 setTimeout(() => {
        console.log("setTimeout qz");
      }, 0);
      console.log("qz");
//输出结果
//qz
//setTimeout qz

2.先执行主线程的同步任务,构造函数是同步任务,先打印aaa语句,在打印qz,主线程的语句没了,然后查看异步线程,promise.then是微任务,所以先打印.then和bbb,定时器宏任务最后执行

代码语言:javascript
复制
 Promise.resolve().then((value) => console.log(".then"));
      setTimeout(() => {
        console.log("定时器");
      }, 0);
      new Promise((resolve) => {
        console.log("aaa");
        resolve();
      }).then((res) => {
        console.log("bbb");
      });
      console.log("qz");
//输出结果
//aaa
//qz
//.then
//bbb
//定时器

3,先执行主线程内容,打印qqzz,aaa,qz主线程没内容,开始执行异步队列中为微任务,打印.then,bbb,此时微任务没了,开始执行宏任务,打印定时器,因为定时器中含有微任务和宏任务,所以继续打印ccc,再执行定时器中的宏任务ddd,最后打印eee

代码语言:javascript
复制
Promise.resolve().then((value) => console.log(".then"));

      setTimeout(() => {
        console.log("定时器");

        new Promise((resolve) => {
          console.log("ccc");
          resolve();
        }).then((res) => {
          console.log("ddd");
        });
        
      }, 0);

      console.log("qqzz");

      new Promise((resolve) => {
        console.log("aaa");

        setTimeout(() => {
          console.log("eee");
        }, 0);

        resolve();
      }).then((res) => {
        console.log("bbb");
      });

      console.log("qz");
      //输出结果
      //qqzz
      //aaa
      //qz
      //.then
      //bbb
      //定时器
      //ccc
      //ddd
      //eee

总结

1.主线程读取JS代码,环境为同步环境,将同步任务分为对应的堆和执行栈

2.同时,主线程执行中遇到异步任务,会将其推给异步进程进行处理,webAPI

3.异步任务对异步任务进行处理,遵循先进先出的顺序依次推入任务队列(异步队列)

4.主线程执行完同步队列之后,查询任务队列,按顺序执行微任务,待微任务执行完毕后执行宏任务

5.形成事件循环

执行顺序 : 同步任务 > process.nextTick > 微任务 > 宏任务 > seImmediate

hljs.highlightAll();

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022-08-290,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • js运行机制
    • 宏任务
      • 微任务
        • 运行机制
          • 代码案例
            • 总结
            领券
            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档