🤟🏼 冇事来学系--Vue2.0async/await使用和EventLoop了解

356 阅读4分钟

「这是我参与11月更文挑战的第25天,活动详情查看:2021最后一次更文挑战」。

async/await使用

async/await是ES8引入的新语法,用来简化Promise异步操作。在此之前,我们只能用链式.then( )的方式处理Promise异步操作

async/await的基本使用

  • 如果某个方法的返回值是Promise实例对象使用await修饰后就是一个真正的值(promise的结果值)
  • 如果一个方法内部用到了await,则这个方法必须使用async来修饰(这两个关键字是成对出现的)
import thenFs from 'then-fs'

// 按照顺序读取文件1,2,3的内容
async function getAllFile(){
	const r1 = await thenFs.readFile('./files/1.txt','utf8')
  console.log(r1)
  const r2 = await thenFs.readFile('./files/2.txt','utf8')
  console.log(r2)
  const r3 = await thenFs.readFile('./files/3.txt','utf8')
  console.log(r3)
}

getAllFile()
  • async函数是一个特殊的函数,其返回结果是一个promise对象,这个对象的状态由它修饰的函数内部return语句决定

  • 如果await修饰的promise对象是失败的状态,则需要用try{ }catch(e){ }来捕获错误


注意事项

在async方法中,第一个await之前的代码会同步执行,await之后的代码会异步执行 (异步任务会等同步任务执行完后才执行)

import thenFs from 'then-fs'

console.log('A')
async function getAllFile(){
	console.log('B')
  const r1 = await thenFs.readFile('./files/1.txt','uft8')
  const r2 = await thenFs.readFile('./files/2.txt','uft8')
  const r3 = await thenFs.readFile('./files/3.txt','uft8')
	console.log(r1, r2, r3)
  console.log('D')
}

getAllFile()
console.log('C')



// 最终的输出顺序
A
B			
C 
111 222 333
D

// console.log('B')是同步执行的,console.log(r1, r2, r3)和console.log('D')是异步执行的
// 在打印完B后,js主线程就退出了后续代码的执行(异步任务等同步任务执行完之后再执行),接着就执行console.log('C')
// 当异步的操作结束后就开始打印r1, r2, r3,最后打印D

EventLoop

javascript是一门单线程执行的编程语言。即同一时间只能做一件事

单线程执行任务队列问题:

如果前一个任务非常耗时,则后续的任务就不得不一直在等待,从而导致程序假死的问题

为了防止某个耗时任务导致程序假死的问题,JS把待执行的任务分为两类:

1. 同步任务(synchronous)

    • 又称为非耗时任务,指在主线程上排队执行的任务
    • 只有前一个任务执行完成,才会执行后一个任务

2. 异步任务(asynchronous)

    • 又称为耗时任务,异步任务由JS委托给宿主环境进行执行(宿主环境就是JS的执行环境,比如是在浏览器运行JS的,那么浏览器就是JS的宿主环境;如果是在node.js中执行JS的,那么node就是宿主环境)
    • 当异步任务执行完成后,会通知JS主线程执行异步任务的回调函数

JS主线程执行完同步任务后,会从"任务队列"中读取异步任务的回调函数,放到执行栈中依次执行。这个过程是循环不断的,所以这种运行机制又被称为EventLoop(事件循环)

宏任务和微任务

JS把异步任务进行了划分

  • 宏任务(macrotask)

异步Ajax请求、setTimeout( )和setInterval( ) 、文件操作、其他宏任务

  • 微任务(microtask)

Promise.then( ), .catch( ), .finally( ) 、process.nextTick、其他微任务

宏任务与微任务的执行顺序

注意:每一个宏任务执行完后都会检查是否存在待执行的微任务

**在执行完同步任务后,会在异步任务队列中查找微任务,若存在微任务则会优先执行微任务。所有微任务执行完之后才执行下一个宏任务


// 分析下面代码的执行顺序

setTimeout(function(){
	console.log(1)
})

new Promise(function(resolve){
	console.log(2)
  resolve()
}).then(function(){
	console.log(3)
})

console.log(4)


// 正确的输出顺序是2431
// setTimeout 是宏任务,会放到宏任务队列中等待执行
// new Promise 是同步任务。所以会先输出2。然后.then()是微任务,会放到微任务队列中等待执行
// 接着会输出4。此时执行完了同步任务,会读取任务队列中的任务,检查是否存在微任务,因此输出3
// 执行完所有微任务后,就执行下一个宏任务,即输出1

跋尾

本篇内容就到这里了~ 我是Zeus👩🏻‍🚀来自一个互联网底层组装员,下一篇再见! 📖