咱们先看道面试题

让写出console.log的打印顺序

console.log(100);setTimeout(()=>{console.log(200);
})setTimeout(()=>{console.log(201);
})Promise.resolve().then(()=>{console.log(300);
})console.log(400);// 100 400 300 200 201
// 为什么300比200先打印

为什么300比200先打印这里就引出了宏任务和微任务????


什么是宏任务和微任务

宏任务包括:setTimeout setInterval Ajax DOM事件
微任务:Promise async/await
微任务宏任务的执行时间要早(必须得记住)


异步和单线程

异步和单线程是相辅相成的,js是一门单线程脚本语言,所以需要异步来辅助

异步和同步的区别:

  • 异步不会阻塞程序的执行,
  • 同步会阻塞程序的执行,

前端使用异步的场景:

  1. 定时任务:setTimeoutsetInverval
  2. 网络请求:ajax请求,动态<img>加载
  3. 事件绑定
//ajax请求代码示例
console.log('start')
$.get('./data1.json',function(data1){console.log(data1)
})
console.log('end')

加载示例:

console.log('start')
var img = document.createElement('img')
img.onload = function(){console.log('loaded')
}
img.src = '/xxx.png'
console.log('end')

事件绑定示例:

console.log('start')
document.getElementById('btn1').addEventListener('click',function () {alert('clicked')
})
console.log('end')

也就是请求处理过程中,你不能闲着,会产生异步的请求,回头再处理,然后继续执行下面的请求。

同步阻塞示例:

console.log(1000)
alert(200)
console.log(3000)

上面就是同步阻塞示例,你不点击alert确认窗口,不会打印3000

js绝大部分都是同步,不过多详解;


同步异步问题

首先,你要知道javascript是单线程语言。js任务需要排队顺序执行,如果一个任务耗时过长,后边一个任务也的等着,但是,假如我们需要浏览新闻,但新闻包含的超清图片加载很慢,总不能网页一直卡着直到图片完全出来,所以将任务设计成了两类:

同步任务
异步任务

当我们打开网站时,网页的渲染过程就是一大堆同步任务,像页面骨架和页面元素的渲染,而加载图片、音乐之类的任务就是异步任务,看一下下边导图:
同步和异步任务分别进入不同的执行“场所”,同步进入主线程,异步进入Event Table并注册函数。当指定的事情完成时,Event Table会将这个函数移入任务队列(Event Queue)。主线程内的任务执行完毕为空,就去任务队列(Event Queue)读取对应的函数,进入主线程执行。

上述过程会不断重复,也就是常说的Event Loop(事件循环)。

但是,JS异步还有一个机制,就是遇到宏任务,先执行宏任务,将宏任务放入任务队列(event queue),然后再执行微任务,将微任务放入微任务队列(micro task queue),但是,这两个queue不是一个queue。当你往外拿的时候先从微任务队列里拿这个回调函数,然后再从宏任务的queue拿宏任务的回调函数,如下图:


任务列队和event loop(事件循环)

单线程就意味着,所有的任务都要排队,前一个结束,才会执行后面的任务。如果列队是因为计算量大,CPU忙不过来,倒也算了。但是更多的时候,CPU是闲置的,因为IO设备处理得很慢,例如
ajax读取网络数据。js设计者便想到,主线程完全可以不管IO设备,将其挂起,然后执行后面的任务。等后面的任务结束掉,在反过头来处理挂起的任务。

好,我们来梳理一下:

1)所有的同步任务都在主线程上执行,行成一个执行栈。
2)除了主线程之外,还存在一个任务列队,只要异步任务有了运行结果,就在任务列队中植入一个时间标记。
3)主线程完成所有任务(执行栈清空),就会读取任务列队,先执行微任务队列在执行宏任务队列。
4)重复上面三步。

只要主线程空了,就会读取任务列队,这就是js的运行机制,也被称为 event loop(事件循环)。


执行顺序

  1. 主线程上宏任务、微任务执行顺序
console.log('---start---');//第一轮主线程setTimeout(() => {console.log('setTimeout');  // 将回调代码放入个宏任务队列,第二轮宏任务执行
}, 0);new Promise((resolve, reject) => {console.log('---Promise第一轮微任务同步执行---');//第一轮微任务同步执行resolve()
}).then(()=>{console.log('Promise.then实例成功回调执行'); // 将回调代码放入微任务队列,第一轮宏任务执行完后立即执行
});console.log('---end---');//第一轮主线程结束

执行顺序:主线程 >> 主线程上创建的微任务 >> 主线程上创建的宏任务

  1. 宏任务中包含微任务
// 宏任务队列 1
setTimeout(() => {// 宏任务队列 2.1console.log('timer_1');setTimeout(() => {// 宏任务队列 3console.log('timer_3')}, 0)new Promise(resolve => {resolve()console.log('new promise')}).then(() => {// 微任务队列 1console.log('promise then')})
}, 0)setTimeout(() => {// 宏任务队列 2.2console.log('timer_2')
}, 0)
console.log('========== Sync queue ==========')

执行顺序:主线程 >> 主线程上的宏任务队列1 >> 宏任务队列1中创建的微任务

========== Sync queue ==========1 timer_1
2 new promise
3 promise then
4 timer_2
5 timer_3

//请写出输出内容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');}, 0)async1();new Promise(function(resolve) {console.log('promise1');resolve();}).then(function() {console.log('promise2');});console.log('script end');

js的异步与宏任务(marcroTask)和微任务(microTask)相关推荐

  1. 经久不衰的话题:Js的宏任务(marcroTask)和微任务(microTask)

    文章目录 前言 一.什么是事件循环(Event loops)? 二.什么是宏任务和微任务? 1. 宏任务 2. 微任务 总结 明天,又是充满希望的一天! 前言 最近工作量比较少,闲暇时间看技术博客,一 ...

  2. js 异步执行_js执行机制:同步与异步(宏任务与微任务)

    关于JavaScript,我们需要了解js是一门单线程语言,一切js版的多线程都是用单线程模拟出来的!!而单线程则意味着,所有任务都需要进行排队,前一个任务结束,才会执行后一个任务,如果前一个任务耗时 ...

  3. js三座大山——异步机制和单线程

    js是单线程的,也就是同一时间只能执行一个任务,为了实现异步的机制,js将任务分为同步任务和异步任务.同步任务是指在主线程中执行的任务,异步任务是指在主线程外执行的任务,当异步任务执行完成后会以回调函 ...

  4. js等待异步执行完再执行,js如何让代码同步执行

    JS方法怎么同步执行 . 方法1内部用了var表示内部变量执行完一次后会自动释放:方法2内的变量cc不能与方法1重名:示例代码如下测试可以varstr='';functioncfun(obj){str ...

  5. JS - 15 - 异步、Promise、async、await

    Promise 类似 java 的 Callable then 方法 类似 java 的 Future 下一篇: <JS - 16 - 任务调度.宏任务.微任务.轮询> PromiseA+ ...

  6. node.js的异步

    2019独角兽企业重金招聘Python工程师标准>>> node.js 的异步一般是通过回调函数的方式来实现的 这种方式 模块.回调方法名(参数,function(参数){回调处理 ...

  7. js异步请求php数据,原生JS发送异步数据请求实例详解

    这篇文章主要为大家详细介绍了原生JS发送异步数据请求的相关资料,具有一定的参考价值,感兴趣的小伙伴们可以参考一下 在做项目的时候,有时候需要用到异步数据请求,但是如果这个时候没有框架的依赖,就需要用到 ...

  8. JS对异步循环使用递归,分批进行大量异步请求

    在上次使用了使用将同步请求改成异步请求的方法解决了 大量Ajax同步请求,出现浏览器页面假死,而Loading图标卡死的情况 之后 (详情见如下链接) CSDNhttps://mp.csdn.net/ ...

  9. js同步异步 回调函数

    学js这么久 只知道它是一个单线程的语言,同步异步听了这么多从未深思过. 在写ajax请求时再一次看见回调函数,想到在网上去查查详细的知识,没想到查出一大堆讲同步异步的,看了不少人的文章,这才感觉自己 ...

最新文章

  1. 数据中心的7个新兴发展趋势
  2. linux网络配置总结,linux中的网络配置命令的总结
  3. DNS服务在网络中的应用
  4. 凯文·凯利:下一个5000天的12个必然趋势!
  5. mvc基础系列说谈(5)——参数与值传递,提交数据
  6. 事件驱动数据管理 微服务和分布式数据管理问题
  7. 134. Gas Station加油站
  8. “约见”面试官系列之常见面试题之第八十二篇之MVC(建议收藏)
  9. ajax中async_小猿圈web前端之ajax的同步和异步有怎样的区别?
  10. 愚人节谁最皮?华为宣布攻克兽语,小米6复刻版官宣,微信发万元红包...
  11. C#.Net工作笔记004---visual studio中的小技巧提高开发效率_随时更新
  12. python之计算空间向量夹角
  13. C++_智能指针shared_ptr、unique_ptr、weak_ptr、auto_ptr总结
  14. smtp邮件服务器的作用,smtp服务器是什么意思(smtp服务器作用及使用指南)
  15. linux解决蓝牙和网卡,完全用Deepin Linux娱乐、工作、学习(3)-- 无线网卡及蓝牙设备驱动篇...
  16. excel报表汇总工具
  17. 2021年计算机考证真题二级题库
  18. 正则表达式语法简介说明
  19. 爬虫,第十次实战之线程池(梨视频下载)
  20. 【算法】Sunday算法(模式匹配)

热门文章

  1. 网络共享计算机登录失败,win7添加共享打印机登陆失败怎么办
  2. 【批处理】共享打印机连接
  3. 经典量子力学照片-1927年索尔维会议
  4. 2022 gdcpc题解(10/13)
  5. ~~~~我的简历呦~~~~
  6. 深井软岩巷道群支护技术与应用_双鸭山优质煤矿锚杆厂-订制_双福煤矿支护架...
  7. flask自定义返回response
  8. 智能质检产品Compliance:七大亮点满足企业多样化合规质检、SOP质检需求
  9. 利尔达与紫光展锐、中国电信等行业伙伴共筑NB-IoT安全生态
  10. Linux文件命令精通指南(二)(转)