簡介
- Promise 是一個 建構函式,既然是建構函式, 那麼,我們就可以 new Promise() 得到一個 Promise 的例項;
- 在 Promise 上,有兩個函式,分別叫做 resolve(成功之後的回撥函式) 和 reject(失敗之後的回撥函式)
- 在 Promise 建構函式的 Prototype 屬性上,有一個 .then() 方法,也就說,只要是 Promise 建構函式建立的例項,都可以訪問到 .then() 方法
- Promise 表示一個 非同步操作;每當我們 new 一個 Promise 的例項,這個例項,就表示一個具體的非同步操作;
- 既然 Promise 建立的例項,是一個非同步操作,那麼,這個 非同步操作的結果,只能有兩種狀態:
- 狀態1: 非同步執行成功了,需要在內部呼叫 成功的回撥函式 resolve 把結果返回給呼叫者;
- 狀態2: 非同步執行失敗了,需要在內部呼叫 失敗的回撥函式 reject 把結果返回給呼叫者;
- 由於 Promise 的例項,是一個非同步操作,所以,內部拿到 操作的結果後,無法使用 return 把操作的結果返回給呼叫者; 這時候,只能使用回撥函式的形式,來把 成功 或 失敗的結果,返回給呼叫者;
- 我們可以在 new 出來的 Promise 例項上,呼叫 .then() 方法,【預先】 為 這個 Promise 非同步操作,指定 成功(resolve) 和 失敗(reject) 回撥函式;
舉個例子
const fs = require('fs')
function getFileByPaht(fpath) {
var promise = new Promise(function (resolve, reject) {
fs.readFile(fpath, 'utf-8', (err, dataStr) => {
if (err) return reject(err);
resolve(dataStr);
});
});
return promise;
}
getFileByPaht('./files/3.txt')
.then(function (dataStr) {
console.log(dataStr);
}, function (err) {
console.log(err.message);
})
複製程式碼
Promise的內部執行順序
用Promise的 .then()
方法解決地獄回撥
注意: Promise的
reject
部分傳入的函式可以為空,即可不寫檔案讀取失敗後的操作,
getFileByPath('./files/1222.txt')
.then(function (data) {
console.log(data);
return getFileByPath('./files/2.txt');
},
.then(function (data) {
console.log(data);
return getFileByPath('./files/3.txt');
})
.then(function (data) {
console.log(data);
})
複製程式碼
Promise中的異常處理
情況一:在讀取檔案出錯的部分報錯,但不影響後方程式碼的執行
getFileByPath('./files/1222.txt')
.then(function (data) {
console.log(data);
return getFileByPath('./files/2.txt');
}, function (err) {
console.log('讀取失敗:' + err.message);
return getFileByPath('./files/2.txt');
})
.then(function (data) {
console.log(data);
return getFileByPath('./files/3.txt');
})
.then(function (data) {
console.log(data);
})
複製程式碼
情況二:如果前面任何的Promise執行失敗,就停止執行後面的方法(catch捕獲機制)
getFileByPath('./files/1222.txt')
.then(function (data) {
console.log(data);
return getFileByPath('./files/2.txt');
})
.then(function (data) {
console.log(data);
return getFileByPath('./files/3.txt');
})
.then(function (data) {
console.log(data);
})
.catch(function (err) {
console.log('異常捕獲: ' + err.message);
})
複製程式碼