JS 异步进阶

 event loop (事件循环/事件轮询)

  • JS是单线程运行的
  • 异步要基于回调来实现
  • event loop 就是异步回调的原理
JS是如何执行的
  • 从前到后,一行一行执行
  • 有报错,则停止下面的代码运行
  • 先把同步代码执行完毕,再执行异步
event loop 的过程
  1. 同步代码一行一行放在 Call Stack 执行
  2. 遇到异步,会先记录下,等待时机(定时、网络请求等)
  3. 时机到了,就移动到 Callback Queue
  4. 如 Call Stack 为空(即同步代码执行完)event loop 开始工作
  5. 轮询查找 Callback Queue ,如有则移动到 Call Stack 执行
  6. 然后继续轮询查找
DOM 事件和 event loop
  • JS是单线程的
  • 异步(setTimeout、AJAX 等)使用回调,基于 event loop
  • DOM 事件也使用回调,基于  event loop
  • 特别注意:DOM事件(比如点击事件)不属于异步

Promise

async/await

async/await 是同步语法,彻底消灭回调函数

async/await 和 Promise 的关系
  • 执行 async 返回的是 Promise 对象
  • await 相当于 Promise 的 then
  • try...catch 可捕获异常,代替了 Promise 的 catch
async function fn1(){
    return 100 
}

const rest1 = fn1()
console.log( 'rest1', rest1 ) //执行 async 函数,返回的是一个 Promise 对象

res1.then(data=>{
    console.log('data',data)  //100
})

async function fn1(){
    const data = await 400  //相当于 await Promise.resolve(400)
    console.log(data) //400
}
async function f1(){
	console.log(2)
	await f2()
	console.log(5)
}
async function f2(){
	console.log(3)
	await 6
	console.log(7)
}
console.log(1)
f1()
console.log(4)

//最终输出1,2,3,4,7,5

微任务 microTask 和宏任务 macroTask

什么是宏任务?什么是微任务?
  • 宏任务:setTimeout,setInterval,Ajax,DOM事件;宏任务是由浏览器规定的
  • 宏任务:DOM 渲染后触发;
  • 微任务:Promise,async/await;微任务是 ES6 语法规定的
  • 微任务:DOM 渲染前触发
  • 微任务执行的时机要比宏任务早
  • 微任务和宏任务都是异步任务
conslose.log(100)

setTimeout(()=>{
    console.log(200)
})

Promise.resolve().then(()=>{
    console.log(300)
})

conslose.log(400)

//最终输出:100,400,300,200

为什么微任务比宏任务渲染的早?

  • 每次 Call Stack 清空(即每次轮询结束),即同步任务执行完
  • 都是 DOM 重新渲染的机会,DOM 结构如有改变则重新渲染
  • 然后再去触发下一次 Event Loop

async/await面试题

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()
		
//初始化 Promise 的时候,Promise 里面传入的函数会立即执行
new Promise(function(resolve){
	console.log('promise1')
	resolve()
}).then(function(){
	console.log('promise2')
})
		
console.log('script end')

答案如图: 

 for....of (用于异步循环

  

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值