先看一下這一次要講的涉及到的promise的基礎用法
let pms = new Promise((resolve, reject) => {
setTimeout(() => {
if (parseInt(Math.random()*10) > 5) {
console.log('隨機數大於5,算任務成功了')
resolve('還可以傳參哦')
} else {
console.log('隨機數< 5,算任務失敗了')
reject('還可以傳參哦< 5')
}
}, 1500)
})
pms.then((value) => {
console.log('success', value)
}, (reason) => {
console.log('fail', reason)
})
複製程式碼
1.5s後如果隨機的數大於5走resolve()輸出:
'隨機數大於5,算任務成功了', 'success',
小於5走reject(),輸出:
'隨機數< 5,算任務失敗了', 'fail'.
我們先寫promise的這兩個功能:
- 建構函式的引數接受一個函式。
- 函式在被呼叫的時候,會被promise傳入兩個引數resolve跟reject。
function Promise(executor){
executor(resolve, reject)
function resolve(){}
function reject(){}
}
複製程式碼
可以看到一new Promise就會執行傳入的函式,也就是我們起名為executor的函式.
- 大家肯定納悶兒為啥要在executor裡呼叫resolve或者reject,我們裡先上程式碼:
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()
});
}
}
function reject(reason) {
if (self.status === 'pending') {
self.reason = reason;
self.status = 'rejected';
self.onRejectedCallbacks.forEach(onRejected => {
onRejected()
});
}
}
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);
}
}
複製程式碼
-
promise的三種狀:等待pending,成功resolve,失敗rejected.(說直接一點就是用來記錄resolve或者reject是否已經呼叫,也就是常說的那個executor任務執行成功了還是失敗了)
-
這一次我們新增了兩個陣列onFulFilledCallbacks、onRejectedCallbacks用來儲存呼叫then的時候傳的兩個回撥函式(當然如果在呼叫then的時候已經resolve或reject,那就直接執行傳入的函式,不用儲存了),所以executor裡一定會呼叫resolve或者reject中的一個,因為一個函式的執行不是
(邏輯上成功)
就是(邏輯上失敗)
.對應我們寫的例子就是隨機數不是大於5就是小於5. -
executor任務成功了肯定有成功後的結果,失敗了我們肯定也拿到失敗的原因。所以value與reason一個是用來儲存成功的結果,一個是用來儲存失敗的原因。
-
ps:onFulFilledCallbacks、onRejectedCallbacks定為陣列的原因是為了這個功能:
pms.then((value) => {
console.log('success1', value)
}, (reason) => {
console.log('fail1', reason)
})
pms.then((value) => {
console.log('success2', value)
}, (reason) => {
console.log('fail2', reason)
})
//then多次得把這些函式給存起來,到時候成功或者失敗的時候,遍歷依次執行~
複製程式碼
下一張我們進入Promise最迷人的鏈式呼叫.
最最最通俗易懂的promise手寫系列(二)- 鏈式呼叫