Promise原理:promise
根據Promise的三種狀態:
pending: 初始狀態,既不是成功,也不是失敗狀態。
fulfilled: 意味着操做成功完成。
rejected: 意味着操做失敗。
複製代碼
Promise原理實現案例:異步
function MyPromise(fn) {
let self = this;// 使用變量 是爲了保證 this的指向;
self.status = 'pending';
// status 是爲了存儲 promise 的狀態,值分別是 pending resolved rejected
self.value = ''; // 用來存儲成功的回調函數執行時傳進來的參數
self.reason = ''; //用來存儲失敗的回調函數執行時傳進來的參數
self.resCallback = []; // 用來放成功回調事件,當走到then中遇見狀態時pending的時候;
self.rejCallback = [];
// 須要咱們去定義兩個函數 分別去對應 res 和 rej
function resolve(val) {
// promise規定 狀態只能從 pending轉成 rejected或resolved
// 一經改變 就不能再去修改
if(self.status === 'pending'){
self.value = val; // 把傳進來的參數賦給 value屬性
self.status = 'resolved'; // 執行成功 函數, 我讓 狀態變成成功態;
self.resCallback.forEach(item=>{
// item 是成功池子中的成功回調
item&&item(val)
})
}
}
function reject(reason) {
if(self.status === 'pending'){
self.reason = reason;
self.status = 'rejected';
self.rejCallback.forEach(item=>{
// item 是成功池子中的成功回調
item&&item(reason)
})
}
}
try {
// 爲了處理 fn執行失敗的狀況
fn(resolve,reject)
} catch (error) {
// fn執行失敗 直接執行 reject
reject(error)
}
}
// then 函數是在 Mypromise的原型上
MyPromise.prototype.then = function(res,rej){
let self = this;
//
// res2 對應的是 第2個then成功函數;
// rej2 對應的是 第2個then失敗函數
let p = new MyPromise(function(res2,rej2){
// 怎麼去判斷讓 res 執行仍是 rej執行?根據當前的狀態去判斷讓哪一個函數執行
if(self.status === 'resolved'){
try {
let val = res(self.value);
res2(val)
} catch (error) {
rej2(error)
}
}
if(self.status === 'rejected'){
try {
// 第一個then 的失敗函數 執行成功以後; 把函數的return
// 給第二個then的成功回調
let val = rej(self.reason);
res2(val);
} catch (error) {
rej2(error);
}
}
console.log(self.status)
if(self.status === 'pending'){
// 當前仍是等待的狀態,這種狀況通常是異步形成的;
// self.resCallback.push(res);// 如果pending狀態 就把成功回調放到成功事件池
// self.rejCallback.push(rej);// 失敗回調當到失敗事件池
self.resCallback.push(function(val){
try {
let v = res(val);
res2(v);
} catch (error) {
rej2(error)
}
})
self.rejCallback.push(function (reason) {
try {
let v = rej(reason);
res2(v)
} catch (error) {
rej2(error);
}
})
}
})
return p;
}
let p = new MyPromise(function (res,rej) {
// res(123)
// rej(345)
setTimeout(() => {
rej(111)
}, 2000);
});
p.then((data)=>{
console.log(data)
},(err)=>{
console.log(err);
return 'hello'
}).then((data2)=>{
console.log(data2)
},(err2)=>{
console.log(err2)
})
</script>
複製代碼