深入解析 async/await 机制与最佳实践

作者:代码拾荒

时间:2026-10-26

浏览:600

本文详细解析 ES7 提出的 async/await 异步解决方案。介绍 async 函数默认返回 Promise 对象的特性,以及 await 在等待 Promise 结果时的阻塞行为。重点讨论 await 必须在 async 函数内使用、非 Promise 值的处理、串行与并行执行的区别,以及多个 await 中 rejected 状态导致的后续代码中断问题,并提供相应的调用规范。

文章目录

async/await 是什么

async/await 是 ES7 提出的基于 Promise 的解决异步的最终方案。

async

async 是一个加在函数前的修饰符,被 async 定义的函数会默认返回一个 Promise 对象 resolve 的值。因此对 async 函数可以直接 then,返回值就是 then 方法传入的函数。

// async基础语法
async function fun0(){
    console.log(1);
    return 1;
}
fun0().then(val=>{
    console.log(val) // 1,1
})

async function fun1(){
    console.log('Promise');
    return new Promise(function(resolve,reject){
        resolve('Promise')
    })
}
fun1().then(val => {
    console.log(val); // Promise Promise
})

await

await 也是一个修饰符,只能放在 async 定义的函数内。可以理解为等待。

await 修饰的如果是 Promise 对象:可以获取 Promise 中返回的内容(resolve 或 reject 的参数),且取到值后语句才会往下执行;

如果不是 Promise 对象:把这个非 promise 的东西当做 await 表达式的结果。

async function fun(){
    let a = await 1;
    let b = await new Promise((resolve,reject)=>{
        setTimeout(function(){
            resolve('setTimeout')
        },3000)
    })
    let c = await function(){
        return 'function'
    }()
    console.log(a,b,c)
}
fun(); // 3秒后输出: 1 "setTimeout" "function"
function log(time){
    setTimeout(function(){
        console.log(time);
        return 1;
    },time)
}
async function fun(){
    let a = await log(1000);
    let b = await log(3000);
    let c = log(2000);
    console.log(a);
    console.log(1)
}
fun(); 
// 立即输出 undefined 1
// 1秒后输出 1000
// 2秒后输出 2000
// 3秒后输出 3000

async/await 的正确用法

// 使用async/await获取成功的结果

// 定义一个异步函数,3秒后才能获取到值(类似操作数据库)
function getSomeThing(){
    return new Promise((resolve,reject)=>{
        setTimeout(()=>{
            resolve('获取成功')
        },3000)
    })
}

async function test(){
    let a = await getSomeThing();
    console.log(a)
}
test(); // 3秒后输出:获取成功

附:async 与 await 一些注意关键点小结

  • await 关键字必须位于 async 函数内部
  • await 关键字后面需要一个 promise 对象(不是的话就调用 resolve 转换它)
  • await 关键字的返回结果就是其后面 Promise 执行的结果,可能是 resolved 或者 rejected 的值,注意最后执行完的是个值。
  • 不能在普通箭头函数中使用 await 关键字,需要在箭头函数前面添加 async
  • await 用来串行的执行异步操作,现实现并行可以考虑 promise.all

async 与 await 缺点

async 函数中,如果有多个 await 关键字时,如果有一个 await 的状态变成了 rejected,那么后面的操作都不会继续执行,promise 也是同理有这样一个函数async

function getData()
{
let value=await get();
value++;
await set();//set完成后返回数据
return value;
}

直接调用

var value=getData();

是对于这个函数直接调用的时候并不是你想要的返回值,因为 async 方法返回的永远是一个 promise,即使开发者返回的是一个常量,也会被自动调用的 promise.resolve 方法转换为一个 promise。因此对于这种情况,上层调用方法也需要是 async 函数,采用如下方法

async function xxxx(){
var value=await getData();
return value;
}

对于这种调用,如果还存在更高层次的方法调用,那么从底层的异步操作开始,一直到最顶层一个不需要返回值的函数为止,全部的方法都要变成 async。

总结

到此这篇关于 async/await 理解和用法的文章就介绍到这了,更多相关 async/await 用法内容请搜索本站以前的文章或继续浏览下面的相关文章希望大家以后多多支持本站!

实用工具推荐

电子包浆

绿化、压缩、噪点和虚拟水印,自由调节做旧程度。

使用 ›
图片压缩

选择画质和输出格式,预览压缩前后的大小。

使用 ›
相关文章