ES6之async和await

本文深入讲解ES2017引入的Async函数,介绍其作为Generator函数语法糖的特性,包括异步操作的简化、返回Promise对象及Await命令的使用。通过实例对比,展示Async函数在文件读取等异步操作中的优势。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.含义

ES2017 标准引入了 async 函数,使得异步操作变得更加方便。async 函数就是 Generator 函数的语法糖。
Generator 函数就是一个封装的异步任务,或者说是异步任务的容器。异步操作需要暂停的地方,都用yield语句注明。
使用Generator函数实现文件读取

	//封装成Promise对象
	const fs = require('fs');
	const readFile = function(fileName){
	  return new Promise(function(resolve,reject){
	    fs.readFile(fileName,function(error,data){
	      if(error) return reject(error);
	      resolve(data);
	    })
	  })
	}
	//定义Generator函数
	const gen = function*(){
	  const test = yield readFile('./resources/test.md');
	  const test1 = yield readFile('./resources/test1.md')
	  console.log(test.toString());
	  console.log(test1.toString());
	}
	// 手动执行Generator函数
	var g = gen();
	g.next().value.then(data=>{
	  g.next(data).value.then(data=>{
	    g.next(data);
	  })
	})

使用async函数实现文件的读取

	//封装成Promise对象
	const fs = require('fs');
	const readFile = function(fileName){
	  return new Promise(function(resolve,reject){
	    fs.readFile(fileName,function(error,data){
	      if(error) return reject(error);
	      resolve(data);
	    })
	  })
	}
	//定义asyncGen 函数
	const asyncGen = async function(){
	  const test = await readFile('./resources/test.md');
	  const test1 = await readFile('./resources/test1.md')
	  console.log(test.toString());
	  console.log(test1.toString());
	}
	//运行asyncGen 函数
	asyncGen();

在这里插入图片描述

比较之下我们会发现,async函数就是将 Generator 函数的星号(*)替换成async,将yield替换成await,并且在执行的时候直接调用asyncGen()就可以了。
这是因为async函数对Generator 函数进行了以下的改进。

  • 内置执行器:Generator 函数执行必须依靠执行器(co模块),或者自己手动执行,而async函数自带执行器。因此可以使用asyncGen()直接调用执行
  • 更容易理解的语义: async表示函数里有异步操作,await表示紧跟在后面的表达式需要等待结果,相对于*和yield更容易理解。
  • 返回值是Promise:async函数的返回对象是Promise对象
2.返回Promise对象

async函数返回一个Promise对象,async函数内部return语句返回的值,会成为then方法回调函数的参数。

	async function f(){
	  return 'hello world'
	}
	f().then(v=>{
	  console.log(v)
	})

在这里插入图片描述
async函数内部抛出错误,会导致返回的Promise对象变成reject状态

	async function f(){
	  throw new Error('出错了')
	}
	f().then(v=>{},e=>{
	  console.log(e);
	})

在这里插入图片描述
async函数返回的Promise对象,必须等到内部所有await命名后面的Promise对象执行完,才会发生状态改变。即只有async函数内部的异步执行操作执行完,才会执行then方法指定的回调函数。

3.await命令

await关键字必须出现在async函数中
一般来说await命令后面是一个Promise对象,返回该对象的结果,如果不是Promise对象就直接返回对应的值

	async function test1(){
	  console.log('a');
	  return 'b';
	}
	async function test2(){
	  const result = await test1();
	  console.log(result);
	}
	
	test2();

等效于

	function test1(){
	  return new Promise((resolve,reject)=>{
	    console.log('a');
	    resolve('b');
	  })
	}
	function test2(){
	  return new Promise((resolve,reject)=>{
	    test1().then(data=>{
	      const result = data;
	      console.log(result);
	      resolve()
	    })
	  })
	}
	test2();

在这里插入图片描述
任何一个await语句后面的Promise对象变成reject状态,那么整个async函数都会中断执行
如果我们希望前一个异步操作失败,也不要中断后面的异步操作,这是我们可以将await放在try…catch结构里面。

	async function f(){
	  try{
	    await Promise.reject('error')
	  }catch(e){
	  }
	  return await Promise.resolve('hello')
	}
	f().then(v=>{
	  console.log(v);
	})

在这里插入图片描述
如果有多个await命令后面的异步操作,可以让它们同时触发,使用Promise.all

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值