一严望、 promise應用場景
- 1 解決回調(diào)地獄
比如我們經(jīng)秤:撸可能需要異步請求一個數(shù)據(jù)之后作為下一個異步操作的入?yún)?/li>
getData(function(a){
getMoreData(a, function(b){
getMoreData(b, function(c){
getMoreData(c, function(d){
getMoreData(d, function(e){
...
});
});
});
});
});
可以發(fā)現(xiàn)上面的代碼看起來是非尘硖福可怕的笤妙,層層嵌套蚕涤,如果在加上復雜的邏輯判斷癞揉,代碼可讀性會變得非常差纸肉。
但是你如果使用promise的話:
function getData() {
return new Promise(function (resolve, reject) {
resolve(1);
});
}
function getMoreData(arg) {
return new Promise(function (resolve, reject) {
resolve(arg + 10);
});
}
getData().then(function (a) {
console.log(a); // 1
return getMoreData(a);
}).then(function (b) {
console.log(b); // 11
})
把上面代碼再簡潔點兒
getData()
.then(a => getMoreData(a))
.then(b => console.log(b));
- 2 promise 可以實現(xiàn)在多個請求發(fā)送完成后 再得到或者處理某個結果
// 兩個數(shù)據(jù)都回來之后再進行操作
let fs = require('fs');
fs.readFile('./1.txt', 'utf8', function (err, data) {
console.log(data);
})
fs.readFile('./2.txt', 'utf8', function (err, data) {
console.log(data);
})
使用promise的話就可以實現(xiàn):
let fs = require('fs');
function read(url){
return new Promise(function(resolve,reject){
fs.readFile(url,'utf8',function(err,data){
if(err)reject(err);
resolve(data);
})
})
}
Promise.all([read('1.txt'),read('2.txt')]).then(data=>{
console.log(data);
},err=>{
console.log(err);
});
二、promise原理實現(xiàn)
1.最簡單的實現(xiàn)
基于上面的應用場景發(fā)現(xiàn)promise
可以有三種狀態(tài)喊熟,分別是pedding
柏肪、Fulfilled
、 Rejected
芥牌。
Pending Promise
對象實例創(chuàng)建時候的初始狀態(tài)
Fulfilled
可以理解為成功的狀態(tài)
Rejected
可以理解為失敗的狀態(tài)
- 構造一個
Promise
實例需要給Promise
構造函數(shù)傳入一個函數(shù)烦味。傳入的函數(shù)需要有兩個形參,兩個形參都是function
類型的參數(shù)胳泉。分別是resolve
和reject
拐叉。 -
Promise
上還有then
方法,then
方法就是用來指定Promise
對象的狀態(tài)改變時確定執(zhí)行的操作扇商,resolve
時執(zhí)行第一個函數(shù)(onFulfilled)凤瘦,reject
時執(zhí)行第二個函數(shù)(onRejected) - 當狀態(tài)變?yōu)?code>resolve時便不能再變?yōu)?code>reject,反之同理案铺。
基于上面描述我們可以實現(xiàn)一個這樣的promise
function Promise(executor){ //executor執(zhí)行器
let self = this;
self.status = 'pending'; //等待態(tài)
self.value = undefined; // 表示當前成功的值
self.reason = undefined; // 表示是失敗的值
function resolve(value){ // 成功的方法
if(self.status === 'pending'){
self.status = 'resolved';
self.value = value;
}
}
function reject(reason){ //失敗的方法
if(self.status === 'pending'){
self.status = 'rejected';
self.reason = reason;
}
}
executor(resolve,reject);
}
Promise.prototype.then = function(onFufiled,onRejected){
let self = this;
if(self.status === 'resolved'){
onFufiled(self.value);
}
if(self.status === 'rejected'){
onRejected(self.reason);
}
}
module.exports = Promise;