異步編程的最高境界,就是根本不用關心它是否是異步。(筆記)

async 函數是什麼?一句話,async 函數就是 Generator 函數的語法糖。javascript

有一個 Generator 函數,依次讀取兩個文件。
var fs = require('fs');
var readFile = function (fileName){
  return new Promise(function (resolve, reject){
    fs.readFile(fileName, function(error, data){
      if (error) reject(error);
      resolve(data);
    });
  });
};

var gen = function* (){
  var f1 = yield readFile('/etc/fstab');
  var f2 = yield readFile('/etc/shells');
  console.log(f1.toString());
  console.log(f2.toString());
};
寫成 async 函數,就是下面這樣。
var asyncReadFile = async function (){
  var f1 = await readFile('/etc/fstab');
  var f2 = await readFile('/etc/shells');
  console.log(f1.toString());
  console.log(f2.toString());
};
一比較就會發現,async 函數就是將 Generator 函數的星號(*)替換成 async,將 yield 替換成 await,僅此而已。

http://www.ruanyifeng.com/blo...
上面這一段是阮一峯老師的講解。html

https://segmentfault.com/a/11...
詳情就是邊城大佬的透徹講解java

注意點

await 命令後面的 Promise 對象,運行結果多是 rejected,因此最好把 await 命令放在 try...catch 代碼塊中。shell

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

// 另外一種寫法

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

await 命令只能用在 async 函數之中,若是用在普通函數,就會報錯。segmentfault

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

  // 報錯
  docs.forEach(function (doc) {
    await db.post(doc);
  });
}

上面代碼會報錯,由於 await 用在普通函數之中了。可是,若是將 forEach 方法的參數改爲 async 函數,也有問題。promise

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

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);
}
相關文章
相關標籤/搜索