const MyPromise = (() => {
// 定義三種狀態
const PENDING = 'pending';
const RESOLVED = 'resolved';
const REJECTED = 'rejected';
// 不讓外界訪問的狀態數據
const PromiseStatus = Symbol('PromiseStatus'); // 當前狀態
const PromiseValue = Symbol('PromiseValue'); // 當前數據
const changeStatus = Symbol('changeStatus'); // 封裝推向的狀態函數
// 定義任務隊列
const thenables = Symbol('thenables');
const catchables = Symbol('catchables');
// 定義後續處理函數
const settleHandle = Symbol('settleHandle');
// 創建串聯Promise
const linkPromise = Symbol("linkPromise");
// 定義構造器
return class MyPromise {
// newStatus 新的狀態 newValue // 新的數據 queue // 任務隊列
[changeStatus](newStaus, newValue, queue) {
// 只能是單向
if (this[PromiseStatus] !== PENDING) {
return
}
this[PromiseStatus] = newStaus;
this[PromiseValue] = newValue;
queue.forEach(hander => hander(newValue))
}
constructor(executor) {
this[PromiseStatus] = PENDING; // 初始狀態是爲pending
this[PromiseValue] = undefined; // 初始數據爲undefined
// 定義任務隊列的數組
this[thenables] = []; // resolveed
this[catchables] = []; // rejected
// 定義成功和失敗的推向函數
const resolve = data => {
this[changeStatus](RESOLVED, data, this[thenables])
}
const reject = reason => {
this[changeStatus](REJECTED, reason, this[catchables])
}
// 可以使用new Error 推向 reject
try {
executor(resolve, reject)
} catch (error) {
reject(error)
}
}
// 定義then方法
then(thenable, catchable) {
return this[linkPromise](thenable, catchable)
}
// 定義catch方法
catch (catchable) {
return this[linkPromise](undefined, catchable)
}
// hander 後續處理函數
// immediateStatus 立即執行的狀態
// queue 作業隊列
[settleHandle](handler, immediateStatus, queue) {
if (typeof handler !== "function") {
return
}
if (this[PromiseStatus] === immediateStatus) {
setTimeout(() => {
handler(this[PromiseValue])
}, 0)
} else {
queue.push(handler)
}
}
// 定義串聯函數
[linkPromise](thenable, catchable) {
function exec(data, handler, resolve, reject) {
try {
//得到promise的處理結果
const result = handler(data);
if (result instanceof MyPromise) {
result.then(d => {
resolve(d)
}, err => {
reject(err)
})
} else {
resolve(result)
}
} catch (err) {
reject(err);
}
}
return new MyPromise((resolve, reject) => {
this[settleHandle](data => {
exec(data, thenable, resolve, reject)
}, RESOLVED, this[thenables])
this[settleHandle](reason => {
exec(reason, catchable, resolve, reject)
}, REJECTED, this[catchables])
})
}
static all(proms) {
return new Promise((resolve, reject) => {
const results = proms.map(p => {
const obj = {
result: undefined,
isResolved: false
}
p.then(data => {
obj.result = data;
obj.isResolved = true;
const unResolved = results.filter(r => !r.isResolved);
if (unResolved.length === 0) {
// 全部完成
resolve(results.map(r => r.result))
}
}, reson => {
reject(reson)
})
return obj;
})
})
}
static race(data) {
return new Promise((resolve, reject) => {
proms.forEach(p => {
p.then(data => {
resolve(data);
}, err => {
reject(err);
})
})
})
}
static resolve(data) {
if (data instanceof MyPromise) {
return data
} else {
return new MyPromise(resolve => {
resolve(data);
})
}
}
static reject(reason) {
return newMyPromise((resolve, reject) => {
reject(reason)
})
}
}
})()
手寫Promise源碼
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.