首先咱們來看一個小案例javascript
data文件夾下是三個文件,咱們要寫一個代碼分別依次讀取三個文件,使得按照 abc 的順序輸出java
fs.readFile('./data/a.txt', 'utf8', function (err, data) { if (err) { // 拋出異常 // 1. 阻止程序的執行 // 2. 把錯誤消息打印到控制檯 throw err } console.log(data) }) fs.readFile('./data/b.txt', 'utf8', function (err, data) { if (err) { throw err } console.log(data) }) fs.readFile('./data/c.txt', 'utf8', function (err, data) { if (err) { throw err } console.log(data) })
這樣寫沒法保證文件內容輸出的順序,應爲讀取文件函數爲異步函數,那麼如何解決這樣的問題呢?程序員
首先咱們能夠想到用嵌套的方法,後輸出的放在代碼最內部,先輸出的放在代碼最外部,可是這樣一層層的嵌套使用,幾個異步函數還好,當函數不少時就會顯得很是不美觀,並且不容易修改,還會產生一系列問題,這就產生了下面的回調地獄問題promise
下圖代碼就是回調地獄的一種,是否是像衝擊波同樣衝擊着廣大程序員的幼小的心靈。(豪油根~~~)markdown
var fs = require('fs') fs.readFile('./data/a.txt', 'utf8', function (err, data) { if (err) { throw err } console.log(data) fs.readFile('./data/b.txt', 'utf8', function (err, data) { if (err) { throw err } console.log(data) fs.readFile('./data/c.txt', 'utf8', function (err, data) { if (err) { throw err } console.log(data) }) }) })
接下來咱們用 ES6新增的Promise來解決回調地獄問題異步
當 p1 讀取成功的時候
當前函數中 return 的結果就能夠在後面的 then 中 function 接收到ide
上面那些 return 的數據實際上是沒什麼der用的函數
真正有用的是:咱們能夠 return 一個 Promise 對象ui
當 return 一個 Promise 對象的時候,後續的 then 中的 方法的第一個參數會做爲 p2 的 resolveatom
var fs = require('fs') var p1 = new Promise(function (resolve, reject) { fs.readFile('./data/a.txt', 'utf8', function (err, data) { if (err) { reject(err) } else { resolve(data) } }) }) var p2 = new Promise(function (resolve, reject) { fs.readFile('./data/b.txt', 'utf8', function (err, data) { if (err) { reject(err) } else { resolve(data) } }) }) var p3 = new Promise(function (resolve, reject) { fs.readFile('./data/c.txt', 'utf8', function (err, data) { if (err) { reject(err) } else { resolve(data) } }) }) p1 .then(function (data) { console.log(data) return p2 }, function (err) { console.log('讀取文件失敗了', err) }) .then(function (data) { console.log(data) return p3 }) .then(function (data) { console.log(data) console.log('end') })