從零實現一個promise
阿新 • • 發佈:2021-07-28
切入點從場景描述出發,即先定義好我們要實現的功能
執行器函式
建構函式入參 executor 自執行函式。會在在 new 的時候同步執行,傳入 resolve 和 reject 狀態扭轉函式。自執行函式內部根據非同步任務執行結果(成功或失敗)呼叫狀態扭轉函式,把狀態傳遞給後續的 then。
狀態轉化
promise 有三種狀態,預設是 pending,成功之後為 fulfilled,失敗之後為 failed。且狀態一旦發生改變,之後不可再改變也不可逆
then 方法
then 方法接受兩個函式,表示成功、失敗狀態下的回撥函式。回撥函式中 return 中值會當作引數傳給後續的then。以此實現鏈式呼叫。
判斷一個變數是否為 promise 需要兩個條件,首先要是物件,然後物件上有 then 方法,以此得出 then 執行的結果也是一個 promise
https://www.51220.cn 51220網站目錄
實現
class Promise {
constructor(executor){
this.status = 'pending',
this.value = undefined;
this.reason = undefined;
this.onFulfilled =undefined;
this.onRejected = undefined;
this.onFulfilledList = [];
this.onRejectedList = [];
try {
executor(this.resolve, this.reject);
} catch(e) {
this.reject(e)
}
}
resolve(value){
if(this.status == 'pending') {
this.status = 'fullfilled';
this.value = value;
this.onFulfilledList.forEach(item => item())
}
}
reject(reason){
if(this.status == 'pending') {
this.status = 'rejected';
this.reason = reason;
this.onRejectedList.forEach(item => item())
}
}
then(onFulfilled, onRejected){
// then 之後要返回一個新的 promise
let result;
if(this.status == 'fullfilled' && onFulfilled) {
result = onFulfilled(this.value)
return Promise.resolve(result);
}
if(this.status == 'rejected' && onRejected) {
result = onRejected(this.reason);
return Promise.resolve(result);
}
if(this.status == 'pending') {
onFulfilled && this.onFulfilledList.push(()=>onFulfilled(this.value));
onRejected && this.onRejectedList.push(() => onRejected(this.reason));
}
}
}
Promise.resolve = function(value) {
if(typeof value == 'object' && value.then) {
return value;
} else {
return new Promise((resolve, reject)=>{
resolve(value)
})
}
}
Promise.all = function(list) {
return new Promise((resolve,reject) => {
let result = [];
let count = 0;
for(let i = 0; i < list.length; i++) {
if(typeof list[i] == 'object' && list[i].then) {
Promise.resolve(list[i]).then(data =>{
result[i] = data;
count++;
},reject)
}else {
result[i] = list[i];
count++;
}
}
if(count == list.length) {
resolve(result);
}
})
}
// Promise.race 同理,只要有一個成功,全部 resolve
// Promise.finally 不管成功失敗,傳遞的回撥函式都會執行,執行之後仍然可以跟then