function MyPromise (execute) {
// value 記錄異步任務成功的執行結果
this.value = null;
// reason 記錄異步任務失敗的執行結果
this.reason = null;
// status 記錄當前狀態,初始化pending
this.status = 'pending';
this.onResolvedQueue = [];
this.onRejectedQueue = [];
let self = this;
function resolve(value) {
if(self.status !== 'pending' ) {
return
}
// 異步任務成功,把結果賦值給value
self.value = value;
// 把當前狀態切換為resolved
self.status = 'resolved';
self.onResolvedQueue.forEach(resolved => resolved(self.value))
}
function reject(reason) {
if(self.status !== 'pending' ) {
return
}
// 異步任務失敗,把結果賦值給value
self.reason = reason;
// 把當前狀態切換為rejected
self.status = 'rejected';
self.onRejectedQueue.forEach(rejected => rejected(self.reason))
}
// 把resolve和reject能力 賦予執行器
try {
execute(resolve, reject);
}catch(e) {
reject(e)
}
}
// then方法接受兩個函數作為入參(可選)
MyPromise.prototype.then = function (onResolved, onRejected) {
// 注意, onResolved 和 onRejected 必須是函數; 如果不是,我們此處用一個透傳來兜底
if(typeof onResolved !== 'function') {
onResolved = function(x) {return x};
}
if(typeof onRejected !== 'function') {
onRejected = function(e) {throw e};
}
let self = this;
// 保存返回值x
let x = null;
// resolve 狀態處理函數
function resolveByStatus(resolve, reject) {
// 包裝成異步, 確保在then后執行
setTimeout(() => {
try {
x = onResolved(self.value)
resolutionProcedure(promise2, x, resolve, reject);
} catch(e) {
reject(e)
}
})
}
// reject 狀態處理函數
function rejectByStatus(resolve, reject) {
setTimeout(() => {
try {
x = onRejected(self.reason)
resolutionProcedure(promise2, x, resolve, reject);
} catch(e) {
reject(e)
}
})
}
let promise2 = new MyPromise((resolve, reject) => {
// 判斷是否是resolved狀態
if(self.status === 'resolved') {
// 如果是 執行對應的處理方法
resolveByStatus(resolve, reject)
} else if(self.status === 'rejected') {
// 若是rejected 狀態, 則執行rejected 對應方法
rejectByStatus(resolve, reject)
} else if(self.status === 'pending') {
self.onResolvedQueue.push(() => resolveByStatus(resolve, reject))
self.onRejectedQueue.push(() => rejectByStatus(resolve, reject))
}
})
return promise2;
}
function resolutionProcedure(promise2, x, resolve, reject) {
// 不被重復執行
let hasCalled = null;
if(x === promise2) {
return reject(new TypeError('循環引用'))
} else if((typeof x === 'object'&& x !== null) || typeof x === 'function') {
try {
let then = x.then;
if(typeof then === 'function') {
then.call(x, (y) => {
if( hasCalled ) return
hasCalled = true;
resolutionProcedure(promise2, y, resolve, reject);
}, (err) => {
if( hasCalled ) return
hasCalled = true;
reject(err)
})
} else {
// 如果then不是function, 則x為參數執行promise
resolve(x);
}
} catch(e) {
if( hasCalled ) return
hasCalled = true;
reject(err)
}
} else {
// 如果x不是object或者function, 則x為參數執行promise
resolve(x);
}
}
let promise2 = new MyPromise(function(resolve, reject) {
// let MyPromise = new Promise(function(resolve, reject) {
resolve('成了');
})
promise2.then((value) => {
console.log('value:', value, '第一個任務')
return '我第一個個任務傳遞過來的'
}).then((value) => {
console.log('第二個任務', value)
})