【JavaScript】async 函数

async

async 函数是 Generator 函数的语法糖(说白了就是更好用些)

async函数,就是将 Generator 函数的星号 * 替换成 async,将 yield 替换成 await ,仅此而已

async function show() { // async 表示这个函数里面有异步的任务
    await '33'; // await 表示后面的结果需要等待,然后再处理
};
let p1 = show();

async & Generator

  1. Generator 函数的执行必须靠执行器,而 async 函数自带执行器。就是说,Generator 函数需要手动地调用 next();而 async 函数的执行,与普通函数一样
  2. asyncawait,比起 *yield,语义更清楚。async 表示函数里有异步操作,await 表示后面的表达式需要等待结果
  3. 正常情况下,await 命令后面是一个 Promise 对象。如果不是,会转成一个立即 resolvePromise 对象
  4. 返回值是 Promise:这比 Generator 函数的返回值是 Iterator 对象方便;可以用 then 方法指定下一步的操作

async 函数可以看作是多个异步操作,包装成的一个 Promise 对象。而 await 就是内部 then 命令的语法糖

async 的使用

  1. await 只能放到 async 函数中使用
  2. async 函数的返回值:一个 Promise 对象
async function show() {
    await '33';
    return 1;
};
let p1 = show();
console.log(p1); // Promise {<pending>}
p1.then(res => {
    console.log(res); // 1
});
  1. 只要 await 语句后面的 Promise 的状态变成 reject,整个 async 函数会中断
async function fn() {
    await Promise.reject('出错了');
    console.log(1); // 不会被执行
};
fn().then(null, err => {
    console.log(err); // 出错了
});
  1. 如果 await 后面的语句出错,函数将中断,后面的语句将不会被执行
async function fn() {
    throw new Error('出错了');
    console.log(1); // 不会被执行
};
fn().catch(err => {
    console.log(err); // Error: 出错了
});

解决报错问题

1. 使用 try{} catch(){}
async function fn() {
    try {
        await Promise.reject('出错了');
    } catch (e) {
        let a = await Promise.resolve("成功了");
        console.log(a);
    };
};
2. 添加 catch 捕获错误

本来 await 后面的就是 Promise 对象,我们就可以直接使用 catch 处理

async function fn() {
    await Promise.reject('出错了').catch(
        err => {
            console.log(err);
        }
    );
    let a = await Promise.resolve("成功了");
    console.log(a);
};
3. 统一捕获错误

个人建议,只要有 await 的地方都 try catch 掉,然后统一处理结果

async function fn() {
    try {
        let f1 = await Promise.resolve('成功了');
        let f2 = await Promise.resolve('成功了');
        let f3 = await Promise.reject('出错了');
    } catch (e) {
        console.log(e);
    };
};
4. 也可以用 Promise.all() 方法

如果你多次请求的数据之间没有关联,就可以使用 Promise.all()

async function fn() {
    let [f1, f2, f3] = await Promise.all([
        Promise.resolve('成功了1'),
        Promise.resolve('成功了2'),
        Promise.resolve('成功了3')
    ]);
    console.log(f1);
    console.log(f2);
    console.log(f3);
};
fn(); // 成功了1 成功了2 成功了3
ajax 请求
function ajax(url) {
    return new Promise((resolve, reject) => {
        $.ajax({
            url,
            type: 'get',
            success: resolve,
            error: reject
        });
    });
};

async function show() {
    try {
        let result = await ajax(`https://jsonplacehouger.typicode.com/todos/1'`);
        let result2 = await ajax(`https://jsonplacehouger.typicode.com/todos/2`);
        let result3 = await ajax(`https://jsonplacehouger.typicode.com/todos/3`);
    } catch (error) {
        console.log('error', error);
    }
};

generator 只是一个过渡期,建议大家用 async

上一篇:SpringBoot 异步任务-使用@Async注解


下一篇:SpringBoot中 线程池