async函数&&await关键字

async函数

基本概念

async 就是 Generator 函数的语法糖

const {promisify} = require('util')
const {readFile} =  require('fs')
const path = require('path')
const file1 = path.join(__dirname,'./txt/1.txt')
const file2 = path.join(__dirname,'./txt/2.txt')
const readFileP = promisify(readFile)
function * fn () {
  let data1 = yield readFileP(file1)
  console.log('读取完数据1' + data1)
  let data2 = yield readFileP(file2)
  console.log('读取完数据2' + data2)
}
fn()

async函数的版本就是将 Generator 函数的星号(*)替换成async,将yield替换成await

定义async函数

使用async关键字定义一个async函数

function * fn () {
  let data1 = yield readFileP(file1)
  console.log('读取完数据1' + data1)
  let data2 = yield readFileP(file2)
  console.log('读取完数据2' + data2)
}

执行async函数

执行async函数则相当于执行了一个自动运行Generator函数,async函数如果返回的结果不是Promise,则会运行结果包装成一个Promise返回:

// async function f() {
//   console.log(1);
// }
// f().then(()=>{
//   console.log(2);
// })

async function f() {
  console.log(1);
  return 'done'
  // 相当于Promise.resolve('done')
}

f().then(value => {
  console.log(value);
})

await关键字

yield类似,async函数中可以使用await关键字,await关键字后面一般会写一个Promise实例,async函数执行的过程中,每次遇到await关键字,会将控制权转回外部环境

  1. 如果await后面是Promise实例,则会等到该 Promise实例被resolve后,才会把本次await到下次await之间的代码推到MircoTask(微任务)中等待执行,并且await的返回值是该Promise实例resolve的值
  2. 如果await后面不是Promise实例,则会立即将本次await到下次await之间的代码推到MircoTask(微任务)中等待执行,并且await的返回值是等于await后面表达式的值:
	async function f() {
	  let data = await new Promise((resolve, reject) => {
	    setTimeout(() => {
	      resolve('a')
	    }, 2000)
	  })
	  console.log(data);
	}
	f()
	console.log('end')
	// end
	// a
  • 如果await后面不是Promise 实例
	async function f() {
	  let data = await 'a'
	  console.log(data);
	}
	f()
	console.log('end'); 
	//end
	//a

async函数的错误处理

如果Promisereject或抛出错误,await之后的代码不会执行,因此,需要使用try..catchawait进行错误捕捉

async function fn () {
  try {
    let data = await new Promise((resolve, reject) => {
      setTimeout(() => {
        reject('123456')
      }, 2000)
    } )
  }catch (e) {
    console.log('发生错误', e)
  }
}
fn ()
// Promise {}
// 发生错误 123456

async函数处理并发异步任务

如果,async函数中的每个await都是等到前面await resolve后才会执行,如果想并发执行,可以使用Promise.all

async function fn () {
//   let time1 = new Date()
//    let data1 = await new Promise((resolve, reject) => {
//       setTimeout(()=> {
//         resolve('123')
//       }, 2000)
//     })
//   let data2 = await new Promise((resolve, reject) => {
//       setTimeout(()=> {
//         resolve('456')
//       }, 3000)
//     })
//   console.log(data1,data2,'用时:'+ (new Date() - time1));
// }
//fn ()
// 123 456 用时:5002
async function fn () {
  let time1 = new Date()
  let [data1, data2] = await Promise.all([
    new Promise((resolve, reject) => {
      setTimeout(()=> {
        resolve('123')
      }, 2000)
    }),
    new Promise((resolve, reject) => {
      setTimeout(()=> {
        resolve('456')
      }, 3000)
    })
  ])
  console.log(data1,data2,'用时:'+ (new Date() - time1));
}
fn ()
// 123 456 用时:3002

你可能感兴趣的:(#,ECMAScript,6,多线程,javascript,async函数)