上一次咱們寫完了Promise的基礎功能,明白了promise爲什麼能在任務成功的時候,調成功的回調函數,爲什麼在任務失敗的時候調失敗的回調函數.今天就把最麻煩的promise鏈式調用給搞定吧.javascript
附上上篇文章的連接:最最最通俗易懂的promise手寫系列(一)
java
再附上上次的代碼吧,以避免翻來翻去麻煩.promise
function Promise(executor) {
let self = this;
self.value = undefined;
self.reason = undefined;
self.status = 'pending';
self.onFulFilledCallbacks = [];
self.onRejectedCallbacks = [];
function resolve(value) {
if (self.status === 'pending') {
self.value = value;
self.status = 'resolved'
self.onFulFilledCallbacks.forEach(onFulFilled => {
onFulFilled(self.value)
});
}
}
function reject(reason) {
if (self.status === 'pending') {
self.reason = reason;
self.status = 'rejected';
self.onRejectedCallbacks.forEach(onRejected => {
onRejected(self.reason)
});
}
}
try {
executor(resolve, reject);
} catch (error) {
reject(error)
}
}
Promise.prototype.then = function (onFulFilled, onRejected) {
if (this.status === 'pending') {
this.onFulFilledCallbacks.push(() => {
onFulFilled(this.value)
});
this.onRejectedCallbacks.push(() => {
onRejected(this.reason)
})
} else if (this.status === 'resolved') {
onFulFilled(this.value);
} else if (this.status === 'rejected') {
onRejected(this.reason);
}
}
複製代碼
咱們要完成的目標:異步
let p = new Promise(function (resove, reject) {
setTimeout(() => {
console.log('任務執行完了');
resove()
},1500)
});
p.then(function (value) {
console.log('第一個成功回調')
},function () {})
.then(function () {
console.log('第二個成功回調')
}, function () {});
輸出以下:
任務執行完了
第一個成功回調
第二個成功回調
複製代碼
rerun this
來作的,但是這裏卻不行,緣由文章末尾再解釋。 咱們採起返回一個新的promise對象來實現鏈式調用.//給這個函數加個返回值,返回值就是一個新new的promise對象
Promise.prototype.then = function (onFulFilled, onRejected) {
let p2 = new Promise((resolve, reject) => {});
if (this.status === 'pending') {
this.onFulFilledCallbacks.push(() => {
onFulFilled(this.value)
});
this.onRejectedCallbacks.push(() => {
onRejected(this.reason)
})
} else if (this.status === 'resolved') {
onFulFilled(this.value);
} else if (this.status === 'rejected') {
onRejected(this.reason);
}
return p2;
}
複製代碼
1.有異步操做,如咱們的例子裏,有setTimout,延時1.5s後打印。函數
任務執行完了
,由於setTimout是異步的)2.沒有異步操做,如咱們的例子裏,有setTimout,延時1.5s後打印。post
//給這個函數加個返回值,返回值就是一個新new的promise對象
Promise.prototype.then = function (onFulFilled, onRejected) {
let p2 = new Promise((resolve, reject) => { resove() });
if (this.status === 'pending') {
this.onFulFilledCallbacks.push(() => {
onFulFilled(this.value)
});
this.onRejectedCallbacks.push(() => {
onRejected(this.reason)
})
} else if (this.status === 'resolved') {
onFulFilled(this.value);
} else if (this.status === 'rejected') {
onRejected(this.reason);
}
return p2;
}
複製代碼
任務執行完了
調用第一個的resolve,第一個成功回調
//給這個函數加個返回值,返回值就是一個新new的promise對象
Promise.prototype.then = function (onFulFilled, onRejected) {
//p2的resolve在裏面,外面拿不到,只有這樣很賤的給在外面記下來了
let p2Resolve ;
let p2Reject;
let p2 = new Promise((resolve, reject) => {
p2Resolve = resolve;
p2Reject = reject;
});
if (this.status === 'pending') {
this.onFulFilledCallbacks.push(() => {
onFulFilled(this.value)
p2Resolve()
});
this.onRejectedCallbacks.push(() => {
onRejected(this.reason)
p2Reject()
})
} else if (this.status === 'resolved') {
onFulFilled(this.value);
p2Resolve()
} else if (this.status === 'rejected') {
onRejected(this.reason);
p2Reject()
}
return p2;
}
複製代碼
輸出以下:
任務執行完了
第一個成功回調
第二個成功回調測試
咱們剩下onFulFilled返回值的功能沒作,下次子再來.
感謝各位觀衆.ui