async 函数的使用

JavaScript 编程中,经常使用到异步交互,因为逻辑嵌套或者请求嵌套,所以出现了 许多延时、数据不同步的问题。从最早的回调函数,到 Promise 对象,再到 Generator 函数,每次都有所改进,但又都有额外的复杂性,都需要理解抽象的底层运行机制。

async函数就是为了解决异步交互的问题而出现的。

async 函数对 Generator 函数的改进,体现在内置执行器、更好的语义及更广的适用性。

async函数的特点

  • 语义化强

  • 里面的await只能在async函数中使用

  • await后面的语句可以是promise对象、数字、字符串等

  • async函数返回的是一个Promsie对象

  • await语句后的Promise对象变成reject状态时,那么整个async函数会中断,后面的程序不会继续执行

函数前面的async关键字,表明该函数内部有异步操作。async也只能使用在函数前,请找对位置,不可以加到将函数赋值给某个值的最前面。

async function asyncPrint(value, ms) {
  await timeout(ms);
  console.log(value)
}
//指定50毫秒以后,输出"hello world"。
asyncPrint('hello world', 50);

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

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

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

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

上面代码会报错,因为 await 用在普通函数之中了,该函数应该为forEach后的普通函数。但是,如果将 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);
}

 

 


版权声明:本文为qq_42822007原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。