欢迎光临
我们一直在努力

ES6 | async和await

async和await

async 函数是 Generator 函数的语法糖。async函数就是将 Generator 函数的星号(*)替换成async,将yield替换成await。async和await,比起星号和yield,语义更清楚。

async表示函数里有异步操作,await表示紧跟在后面的表达式需要等待结果。

async函数返回一个 Promise 对象,可以使用then方法添加回调函数。async函数内部return语句返回的值,会成为then方法回调函数的参数。

async function fn() {
    return 'hello world';
}
fn().then(v => console.log(v)); // "hello world"
console.log('我先执行'); // "我先执行"
console.log( fn() ); // Promise {<resolved>: "hello world"}

async 函数有多种使用形式

// 函数声明
async function foo() {}

// 函数表达式
let foo = async function () {};

// 对象的方法
let obj = { async foo() {} };
obj.foo().then(...)

// Class 的方法
class Storage {
    constructor() {
        this.cachePromise = caches.open('avatars');
    }
    async getAvatar(name) {
        const cache = await this.cachePromise;
        return cache.match(`/avatars/${name}.jpg`);
    }
}
const storage = new Storage();
storage.getAvatar('jake').then(…);

// 箭头函数
let foo = async () => {};

// 立即执行函数
(async function (){
    // ...
})();

async函数内部抛出错误,导致返回的 Promise 对象变为reject状态。抛出的错误对象会被catch方法回调函数接收到。

async function fn() {
    throw new Error('出错了');
}
fn().then(
    v => console.log(v),
    e => console.log(e) // catch Error: 出错了
)

await 命令

正常情况下,await命令后面是一个 Promise 对象,返回该对象的结果。如果不是 Promise 对象,就直接返回对应的值。

async function fn() {
    return await 123;
    // 等同于
    // return 123;
}
fn().then( v => console.log(v) );
// 123

上面代码中,await命令的参数是数值123,这时等同于return 123。

注意,await一定要运行在async 函数内!

当async函数执行的时候,一旦遇到await就会先返回,等到异步操作完成,再接着执行函数体内后面的语句。

(async function (){
    var res1 = await new Promise(function (resolve,reject){
        setTimeout(function (){
            console.log('异步任务1');
            resolve('成功1');
        },1000);
    });
    var res2 = await new Promise(function (resolve,reject){
        setTimeout(function (){
            console.log('异步任务2');
            resolve('成功2');
        },1000);
    });
    console.log(res1,res2);
    console.log('同步任务3');
    console.log('同步任务4');
})();

 await 会等待这个 Promise 完成,并将其 resolve 的结果返回出来。

await命令后面的 Promise 对象如果变为reject状态,则reject的参数会被catch方法的回调函数接收到。

async function fn() {
    await Promise.reject('出错了');
}
fn().then(v => console.log(v)).catch(e => console.log(e))
// 出错了

任何一个await语句后面的 Promise 对象变为reject状态,那么整个async函数都会中断执行。

async function fn() {
    await Promise.reject('出错了');
    await Promise.resolve('hello world'); // 不会执行
}
fn().then(
    v => console.log(v),
    err => console.log(err)
);
// '出错了'

await命令后面的Promise对象,运行结果可能是rejected,所以最好把await命令放在try...catch代码块中。

async function f() {
    try {
        await Promise.reject('出错了');
    } catch(e) {
        console.log(e);
    }
    return await Promise.resolve('hello world');
}
f().then(v => console.log(v));
// hello world

async函数返回的 Promise 对象,必须等到内部所有await命令后面的 Promise 对象执行完,才会发生状态改变,除非遇到return语句或者抛出错误。也就是说,只有async函数内部的异步操作执行完,才会执行then方法指定的回调函数。

(async function (){
    var res1 = await promiseAjax({
        type: 'get',
        url: 'datas.php',
        data: 'userid=abc1001'
    });
    var res2 = await promiseAjax({
        type: 'get',
        url: 'datas.php',
        data: 'userid=abc1002'
    });
    var res3 = await promiseAjax({
        type: 'get',
        url: 'datas.php',
        data: 'userid=abc1003'
    });
    res1 = JSON.parse(res1);
    res2 = JSON.parse(res2);
    res3 = JSON.parse(res3);
    // con.innerHTML = `姓名:${res1.name},身份证:${res2.idcode},地址:${res3.address}`;
    return `姓名:${res1.name},身份证:${res2.idcode},地址:${res3.address}`;
})().then(val=>{
    con.innerHTML = val;
});
赞(0) 打赏
未经允许不得转载:散人研 » ES6 | async和await
分享到: 更多 (0)

评论 抢沙发

1 + 6 =
  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏