Promise本意是承諾,在程式中的意思就是承諾我過一段時間後會給你一個結果。 什麼時候會用到過一段時間?答案是非同步操作,非同步是指可能比較長時間才有結果的才做,例如網路請求、讀取本地檔案等
1.Promise的三種狀態
- Pending Promise物件例項建立時候的初始狀態
- Fulfilled 可以理解為成功的狀態
- Rejected 可以理解為失敗的狀態
then 方法就是用來指定Promise物件的狀態改變時確定執行的操作, resolve 時執行第一個函式(onFulfilled), reject 時執行第二個函式(onRejected)
2.promise的基本用法
const fs = require('fs');
let promise = new Promise((resolve, reject) => {
fs.readFile(__dirname+'/100.txt', 'utf8', function (err, data) {
if (err) return reject(err); //失敗時執行reject
resolve(data);//成功時執行resolve
})
});
promise.then((res) => {
console.log(res)
},(err)=>{
console.log(err)
})
//也可以用catch統一捕獲錯誤
promise.then((res) => {
console.log(res)
})
.catch(err=>{
console.log(err)
})
複製程式碼
3.promise鏈式呼叫解決回撥地獄
- 如果我們要在開啟1.txt之後再開啟2.txt,以前的做法是這樣的
function read(_url,cb){
fs.readFile(__dirname+_url, 'utf8', function (err, data) {
if (err) return
cb&&cb(data)
})
}
read('/1.txt',function(data){
console.log(data)
read('/2.txt',function(data){
console.log(data)
})
})
複製程式碼
- 改成promise的形式
function read(_url){
return new Promise((resolve,reject)=>{
fs.readFile(__dirname+_url, 'utf8', function (err, data) {
if (err) return reject(err)
resolve(data)
})
})
}
read('/1.txt')
.then(res=>{
console.log(res)
return read('/2.txt')//此處要再次返回一個promise物件
})
.then(res=>{
console.log(res)
})
.catch(err=>{
console.log(err)
})
複製程式碼
當第一個then中返回一個promise,會將返回的promise的結果,傳遞到下一個then中。這就是比較著名的鏈式呼叫了。
4.利用Promise.all方法將多個非同步請求的結果在統一彙總
Promise.all([read('/1.txt'),read('/2.txt')])
.then(([res1,res2])=>{
console.log(res1,res2)
})
複製程式碼
5.promise.race賽跑,獲得兩個請求先返回的那個
Promise.race([read('/1.txt'),read('/2.txt')])
.then(res=>{
console.log(res)
})
複製程式碼