js-ES6學習筆記-async函數


1、async 函數是 Generator 函數的語法糖。前文有一個 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,僅此而已。

2、async函數對 Generator 函數的改進,體現在以下四點。

  1. 內置執行器。async函數自帶執行器。也就是說,async函數的執行,與普通函數一模一樣,只要一行。
    var result = asyncReadFile();

    上面的代碼調用了asyncReadFile函數,然后它就會自動執行,輸出最后結果。這完全不像 Generator 函數,需要調用next方法

  2. 更好的語義。asyncawait,比起星號和yield,語義更清楚了。async表示函數里有異步操作,await表示緊跟在后面的表達式需要等待結果。
  3. 更廣的適用性。yield命令后面只能是 Thunk 函數或 Promise 對象,而async函數的await命令后面,可以是Promise 對象和原始類型的值(數值、字符串和布爾值,但這時等同於同步操作)。
  4. 返回值是 Promise。async函數的返回值是 Promise 對象,這比 Generator 函數的返回值是 Iterator 對象方便多了。你可以用then方法指定下一步的操作。

進一步說,async函數完全可以看作多個異步操作,包裝成的一個 Promise 對象,而await命令就是內部then命令的語法糖。

3、async函數返回一個 Promise 對象,可以使用then方法添加回調函數。當函數執行的時候,一旦遇到await就會先返回,等到異步操作完成,再接着執行函數體內后面的語句。

async function getStockPriceByName(name) {
  var symbol = await getStockSymbol(name);
  var stockPrice = await getStockPrice(symbol);
  return stockPrice;
}

getStockPriceByName('goog').then(function (result) {
  console.log(result);
});

函數前面的async關鍵字,表明該函數內部有異步操作。調用該函數時,會立即返回一個Promise對象。

4、另一個例子,指定多少毫秒后輸出一個值。

function timeout(ms) {
  return new Promise((resolve) => {
    setTimeout(resolve, ms);
  });
}

async function asyncPrint(value, ms) {
  await timeout(ms);
  console.log(value);
}

asyncPrint('hello world', 50);

5、async 函數有多種使用形式。

// 函數聲明
async function foo() {}

// 函數表達式
const 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(…);

// 箭頭函數
const foo = async () => {};

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM