ES6中的async、await函数

async是为了解决异步操作,其实是一个语法糖,使代码书写更加简洁。

1. async介绍

async放在一个函数的前面,await则放在异步操作前面。async代表这个函数中有异步操作需要等待结果,在一个async函数中可以存在多个await,也就是多个异步操作,但是需要注意的是await是一个一个发生的,执行完一个异步操作才会执行下一个异步操作,不是并发执行的。

async结果返回一个Promise对象,async结果状态变化可以由三种情况改变

第一种:函数体内有return,return的结果可以通过then方法获取。

第二种:如果await中的异步操作状态变为reject,则会将错误外抛,改变async的状态变为reject。

第三种:当所有await都执行完,并且状态为resolved,则状态会变为resolved,也就是只有所有异步操作执行完,才会执行then方法获取。

2. async可以使用在哪里?

  • 函数声明中
js 复制代码
async function fun() {}
  • 函数表达式
js 复制代码
const fun = async function() {}
  • 对象的方法
js 复制代码
let obj = { async foo() {} };
obj.foo().then()
  • Class的方法
js 复制代码
class Person{
    async age(num) {
        const a = await foo();
    }
}
const p1 = new Person();
p1.age(10).then();
  • 箭头函数
js 复制代码
const foo = async () => {};

3. 使用

js 复制代码
const f1 = async () => {
    await ab();
}
f1.then((resolve) => {
    console.log(resolve);
})

4. 错误处理

await后面一个Promise对象,如果不是则会立即转成Promise对象。

假如有问题的时候会向外抛出错误,会导致async状态变为reject。

假如我们不需要往外抛错误,可以使用try...catch或者在异步操作中添加catch方法,让错误及时处理掉,不往外抛。

js 复制代码
async Function f1 () {
    await Promise.reject('出错了');
    await Promise.resolve('hello word'); // 不会执行了
}

由于抛出错误了,会整个async函数都会中断执行。

js 复制代码
// 改成 第一种解决方法

async Function f1 () {
    try {
        await Promise.reject('出错了');
    }catch (err){
    }
    return await Promise.resolve('hello word');
}

f1.then(res => console.log(res)); // hello word

// 第二种解决方法

async Function f1 () {
    await Promise.reject('出错了').catch((err) => {
        console.log(err);
    })
    return await Promise.resolve('hello world');
}
f1.then(res => console.log(res)); // 出错了  hello word

5. 并发执行代码

正常情况下当async函数内部都多个await时,会执行完一个异步操作才会执行下一个异步操作,是继发执行,而不是并发执行,这样会很慢。

如果await后面的异步操作没有关联的话,则可以完全同时触发。

  • 第一种使用Promise.all()方法
js 复制代码
let [foo, bar] = await Promise.all([getFoo(), getBar()]);
  • 第二种执行方法后await
js 复制代码
let fooPromise = getFoo();
let barPromise = getBar();
let foo = await fooPromise();
let bar = await barPromise();

这样会同时触发异步操作,缩短执行时间。

  • 第三种 for循环、不能map循环
js 复制代码
async function dbFuc (db) {
    let docs = [{}, {}, {}];
    let promises = docs.map(docs => db.post(doc));
    let results = [];
    for (let promise of promisees) {
        results.push(await promise);
    }
    console.log(results);
}
相关推荐
就叫年华吧丶23 分钟前
长文档点目录定位总是不准?一个 content-visibility + 平滑滚动引发的连环坑(Vue3 实战)
前端·javascript·算法·vue
赵得C30 分钟前
创建 SVG 图标预览页面:从零实现到解决 CORS 问题
前端·javascript·html
ljt27249606611 小时前
Vue笔记(九)--defineEmits
javascript·vue.js·笔记
波力海苔夹心脆67511 小时前
C# 序列化与反序列化详解:System.Text.Json、Newtonsoft.Json、XmlSerializer 用法、特性选项与安全实践
经验分享·后端·c#·json·.net
Mr_Mao15 小时前
告别选型困难!集 VueUse、ahooks、Mantine 于一身:286 个 Hook 的 ReaUse 来了
前端·javascript·react.js
默_笙16 小时前
🚙 一条腿走路会摔:ES 关键词检索、混合召回与 ReRank 裁判
前端·javascript
小羊没烦恼!16 小时前
在Scrum中实施敏捷建模
java·开发语言·windows·算法·c#
dsyyyyy110117 小时前
Vue 3 Watch 监视完全指南
前端·javascript·vue.js
Lost of 程序猿17 小时前
建造者模式实战:告别“十参数构造函数“的数据导出任务
后端·设计模式·c#·asp.net
u01110267519 小时前
Vue 3 实现图片裁剪框:拖动、缩放与固定宽高比
前端·javascript·vue.js