《十七》ES6+ 中的 async 函数

本文深入探讨ES8引入的async异步函数,它是Generator生成器函数的语法糖,具有内置执行器、更好语义、更广适用性和返回Promise等优势。文章详细解析async函数的执行过程、返回值、错误处理及await关键字的使用。

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

ES8 引入了 async 异步函数,它是 Generator 生成器函数的语法糖。

async 异步函数对 Generator 生成器函数的改进,体现在以下四点:

  1. 内置执行器:Generator 生成器函数的执行必须依靠执行器,所以才有了 next 方法;而 async 函数自带执行器。也就是说,async 函数的执行与普通函数一模一样,不再需要手动调用 next 方法。
  2. 更好的语义:async 和 await,比起星号和 yield,语义更清楚了。async 表示函数里有异步操作,await 表示紧跟在后面的表达式需要等待结果。
  3. 更广的适用性:async 函数的 awati 命令后面,可以是 Promise 函数和原始类型的值。
  4. 返回值是 Promise:async 函数的返回值是 Promise,这比 Generator 函数的返回值是 Iterator 对象方便多了,可以用 then 指定下一步的操作。进一步说,async 函数完成可以看作是多个异步操作,包装成的一个 Promise 对象,而 await 命令就是内部 then 命令的语法糖。
// 普通函数
function fn() {}

// 生成器函数
function* fn() {}

// async 异步函数 
async function fn() {}
const fn = async function() {}
const fn = async() => {}

async 异步函数内部代码的默认执行过程和普通函数是一样的。默认情况下也是同步执行。

async function fn() {
	console.log(1)
	console.log(2)
}
fn()

请添加图片描述

async 异步函数的返回值:

async 异步函数的返回值是一个 Promise 对象。

  1. 如果没有返回值,默认返回 Promise.resolve(undefined),那么 async 异步函数返回值的状态是 fulfilled。
  2. 如果返回值是一个普通值(非 Promise 类型,且不是 thenable 对象),返回值会被包裹到 Promise.resolve() 中,那么 async 异步函数返回值的状态是 fulfilled。
  3. 如果返回值是一个 Promise,那么 async 异步函数返回值的状态由 Promise 决定。
  4. 如果返回值是一个 thenable 对象,那么 async 异步函数返回值的状态由 then 方法决定。
async function fn() {
	return 1

	// 相当于
	// Promise.resolve(1)
}
fn().then(res => {
	console.log(res) // 1
})

async 异步函数中发生错误:

如果 async 异步函数中发生错误,会中断代码的执行,并且将这个错误抛出,返回值的状态会变为 rejected。

若不捕获错误,将会一层层向上传递,直到被浏览器捕获。

async function fn() {
	console.log(1)
	'Hello'.filter()
	console.log(2)
}

fn().catch(err => {
	console.log(err)
})

请添加图片描述

async 异步函数中的 await 关键字:

await:意思是等待。可以在 async 异步函数内部使用 await 关键字,后面跟一个表达式,它会等待表达式执行完之后才进行下一步操作。

  1. 如果是普通的表达式,其实和不使用 await 没有什么区别。

    async function fn() {
    	// 会依次打印 1、2、3、4
    	await [1,2,3].forEach(item => console.log(item))
    	console.log(4)
    }
    
    fn()
    
    async function fn() {
    	// 发生错误,不会打印 2
    	await 'Hello'.filter()
    	console.log(2)
    }
    
    // 捕获异步函数内部发生的错误
    fn().catch(err => {
    	console.log(err)
    })
    
  2. 通常来说, await 后面跟着的是一个返回 Promise 的表达式。

    • await 会等到后面跟着的 Promise 的状态变为 fulfilled 之后,才继续执行下面的代码。
      function asyncFn() {
      	return new Promise(resolve => {
      		setTimeout(() => {
      			console.log(1)
      			resolve()
      		}, 2000)
      	})
      }
      async function fn() {
      	// 等待 2 秒钟打印 1 之后,才会打印 2
      	await asyncFn()
      	console.log(2)
      }
      
      fn()
      
    • 如果后面跟着的 Promise 的状态变为了 rejected,会中断 async 异步函数的执行,将错误抛出,并且 async 异步函数返回值的状态变为 rejected。
      function asyncFn() {
      	return new Promise((resolve, reject) => {
      		setTimeout(() => {
      			console.log(1)
      			reject('出错了')
      		}, 2000)
      	})
      }
      async function fn() {
      	// 等待 2 秒钟打印 1 之后,然后抛出错误;中断了异步函数的执行,不会打印 2
      	await asyncFn()
      	console.log(2)
      }
      
      // 捕获异步函数内部发生的错误
      fn().catch(err => {
      	console.log(err)
      })
      

await 的返回值:

await 返回的是后面表达式的值。

async function fn() {
  const result = await 1 + 2
  console.log(result) // 3
}
f()
async function fn() {
  const result = await Promise.resolve(1)
  console.log(result) // 1
}
f()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值