07月26, 2017

哦,async

async

在异步回调比较多情况下使用 async 确实方面很多。在使用中发现一些注意事项, 以做记录。(FROM 阮一峰async 函数的含义和用法

async 函数返回一个 Promise 对象,可以使用 then 方法添加回调函数。当函数执行的时候,一旦遇到 await 就会先返回,等到触发的异步操作完成,再接着执行函数体内后面的语句。

注意:

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

async function myFunction(){
    try {
        await sometingThatReturnsAPromise();
    } catch (err) {
        console.log(err);
    }
}

//另外一个写法
async function myFunction() {
    await somethingThatReturnsAPromise().catch(function (err){
        console.log(err);
    });
}

await 命令只能用在 async 函数之中,如果用在普通函数,就会报错。

async function dbFuc(db) {
    let docs = [{}, {}, {}];

    //报错
    docs.forEach(function(doc) {
        await db.post(doc);
    });
}

上面代码会报错,因为 await 用在普通函数之中了。但是,如果将 forEach 方法的参数改成async 函数,也有问题。

 async function dbFuc(db) {
     let docs = [{}, {}, {}];

     //可能得到错误结果
     docs.forEach(async function(doc) {
         await db.post(doc);
     })
 }

上面代码可能不会正常工作,原因是这时三个 db.post 操作将是并发执行,也就是同时执行,而不是继发执行。正确的写法是采用 for 循环。

 async function dbFuc(db) {
     let docs = [{}, {}, {}];
     for (let doc of docs) {
         await db.post(doc);
     }
 }

如果确实希望多个请求并发执行,可以使用 Promise.all 方法。

 async function dbFuc(db) {
     let docs = [{}, {}, {}];
     let promises = docs.map( (doc) => db.post(doc));

     let results = await Promise.all(promises);
     console.log(results);
 }

 //或者使用下面的写法

 async function dbFuc(db) {
     let docs = [{}, {}, {}];
     let promises = docs.map( (doc) => db.post(doc));

     let results = [];
     for (let promise of promises) {
         results.push(await promise);
     }
     console.log(results);
 }

本文链接:http://westpsk.com/post/async.html

-- EOF --

Comments