ES6 async await原则探索

本文详细介绍了ES6中新增的异步函数特性,包括async和await关键字的使用,以及它们如何改变异步编程的流程。通过实例演示了await在遇到非Promise和Promise对象时的不同行为,解释了其如何阻塞后续代码执行,直到异步操作完成。

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

ES6中新增异步函数,即在函数声明前加上async即可,使得异步操作更加方便简洁,其中await是在async函数中独有的

在执行过程中一旦遇到await就会先返回,等到异步操作完成之后再接着执行函数后面的语句,这句话是什么意思呢

  1. 一旦遇到await就立刻让出线程,阻塞后面的代码
  2. 如果不是promise,await会阻塞后面的代码,先执行async外面的同步代码,同步代码执行完毕后再回到async内部,把非promise作为await的结果

  3. 如果await右边是promise对象,也会阻塞后面的代码,先执行async外面的同步代码,等待promise对象fulfilled,把resolve的参数作为await表达式的运算结果

以上描述可以用如下代码验证:

function doSomething() {
    console.log('in doSomething');
}

async function test() {
    console.log('test start');
    await doSomething();//会阻塞后面的代码,执行外面代码
    console.log('test end');
}
test();
console.log('outside');
//输出如下
//test start
//in doSomething
//outside
//test end

由上面的代码可以看出执行到await时会中断其后面到代码,执行函数之外到代码,执行完后再回到这里来执行await后面的代码

下面是当await后面是promise对象时

function doSomething() {
    return new Promise((resolve, reject) => {
        resolve('something resolve');
    })
}

async function test() {
    console.log('test start');
    let res = await doSomething();
    console.log(res);
    console.log('test end');
}
test();
console.log('outside');

// 输出结果
// test start
// outside
// something resolve
// test end

await的结果是promise中resolve的参数,但是执行过程是相同的,先阻塞await后面的代码执行外面的同步代码再执行await后面的代码块

### ES6 中 `async` 和 `await` 的工作原理 #### 背景介绍 JavaScript 是一种单线程编程语言,这意味着它在同一时间只能执行一项操作。为了处理异步任务而不阻塞主线程,JavaScript 使用事件循环机制来管理回调函数队列。然而,在传统的基于回调或 Promise 的方式中编写异步代码可能会导致嵌套过深(即所谓的“回调地狱”)。为了解决这一问题ES2017 引入了 `async/await` 关键字作为更简洁和易读的方式来处理异步逻辑。 --- #### 工作原理详解 ##### 1. **`async` 函数** 当一个函数被声明为 `async` 时,该函数会返回一个隐式的 `Promise` 对象[^1]。如果函数内部有显式的 `return` 返回值,则这个值会被自动封装成一个已解决状态的 `Promise`;如果有抛出错误的情况,则会变成拒绝状态的 `Promise`。 ```javascript async function exampleAsync() { return "Hello, world!"; } exampleAsync().then(value => console.log(value)); // 输出: Hello, world! ``` ##### 2. **`await` 表达式** `await` 只能在 `async` 函数内部使用,用于暂停当前函数的执行直到指定的 `Promise` 完成解析并返回其结果[^2]。在此期间,其他非同步的任务可以继续运行而不会受到影响。 - 如果等待的是一个已经完成的 `Promise` 或者是一个普通的值而非真正的 `Promise` 实例,那么 `await` 将立即恢复控制权并将相应数据传递给后续语句。 - 若目标 `Promise` 失败 (`reject`) ,则整个流程也会停止并向上传播异常除非被捕获。 ```javascript // 成功案例 async function fetchUserDataSuccess() { const user = await getUserData(); // 假设这是一个返回 Promise 的 API 请求方法 console.log(user); } // 错误捕获 async function fetchUserDataErrorHandling() { try { const user = await getInvalidUserData(); console.log(user); } catch (error) { console.error('Failed to load data:', error.message); } } ``` ##### 3. **底层实现细节** 实际上,`async/await` 并未改变 JavaScript 执行模型的核心——它们只是语法糖形式简化了对 Promises 的调用过程。每当遇到带有 `await` 的表达式时,编译器会在后台创建一个新的闭包环境保存上下文信息以便稍后再从中断处重新启动程序流[^3]。 --- #### 总结 通过引入 `async/await` 结构,开发者能够写出看起来像顺序执行但实际上却能高效利用资源的异步代码结构。这种方式不仅提高了可维护性和调试便利度,还减少了因复杂嵌套带来的潜在风险。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值