1、解決方案javascript
異步操做是 JavaScript 編程的麻煩事,麻煩到一直有人提出各類各樣的方案,試圖解決這個問題。java
從最先的回調函數,到 Promise 對象,再到 Generator 函數,每次都有所改進,但又讓人以爲不完全。它們都有額外的複雜性,都須要理解抽象的底層運行機制。shell
異步編程的最高境界,就是根本不用關心它是否是異步。編程
async 函數就是隧道盡頭的亮光,不少人認爲它是異步操做的終極解決方案。異步
一句話,async 函數就是 Generator 函數的語法糖。async
前文有一個 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,僅此而已。ui
3、async優勢spa
async 函數對 Generator 函數的改進,體如今如下三點。
(1)內置執行器。 Generator 函數的執行必須靠執行器,因此纔有了 co 函數庫,而 async 函數自帶執行器。也就是說,async 函數的執行,與普通函數如出一轍,只要一行。
var result = asyncReadFile();
(2)更好的語義。 async 和 await,比起星號和 yield,語義更清楚了。async 表示函數裏有異步操做,await 表示緊跟在後面的表達式須要等待結果。
(3)更廣的適用性。 co 函數庫約定,yield 命令後面只能是 Thunk 函數或 Promise 對象,而 async 函數的 await 命令後面,能夠跟 Promise 對象和原始類型的值(數值、字符串和布爾值,但這時等同於同步操做)。