// Promise有狀態,pending,fulfilled,rejected
//創建實體的時候,要丟一個函式進去,形參是resolve,reject兩個方法
//呼叫resolve,就是把pending狀態改為fulfilled,reject()是改為rejected,一旦狀態更改后,就不可以再改了
//先定義三個狀態
const PENDING='pending'
const FULFILLED='fulfilled'
const REJECTED='rejected'
class Mypromise{
constructor(executor){
try {
executor(this.reolve,this.reject)
} catch (error) {//執行器如果發生錯誤,捕獲錯誤,丟給catch
this.reject(error)
}
}
status=PENDING
//成功的值
value=undefined
//失敗的原因
reason=undefined
// 預存盤成功的回呼和失敗的回呼
successCallback=[]
failCallback=[]
reolve=value=>{//這個value是成功之后的值
//用來更改狀態
if(this.status!==PENDING)return
this.status=FULFILLED
//保存成功的值,給then的成功回呼
this.value=value
// 如果有成功的回呼,就呼叫一下
// while(this.successCallback.length){
// this.successCallback.shift()(this.value)
// }
while(this.successCallback.length){
this.successCallback.shift()()
}
// if(this.successCallback)this.successCallback(this.value)
}
reject=reason=>{//reason是失敗的原因
if(this.status!==PENDING)return
//更改為失敗的狀態
this.status=REJECTED
//保存失敗的值,給then的失敗回呼
this.reason=reason
//如果有失敗的回呼,就呼叫一下
// if(this.failCallback)this.failCallback(this.reason)
// while(this.failCallback.length){
// this.failCallback.shift()(this.reason)
// }
while(this.failCallback.length){
this.failCallback.shift()()
}
}
//實體身上的then和catch方法
//then的引數是兩個函式,第一函式是正確的時候回呼,第二個引數是錯誤時候的回呼,then的回傳是新的promise,實作鏈式呼叫
//成功回呼有個引數,是成功之后的值
//失敗回呼有個引數,是失敗的原因
then(successCallback,failCallback){
//如果then沒有引數,則默認補充一個引數,把值原樣丟給下一個then
successCallback=successCallback?successCallback:value=>value
failCallback=failCallback?failCallback:reason=>{throw reason}
let promise2=new Mypromise((resolve,reject)=>{
if(this.status=== FULFILLED){
setTimeout(()=>{//因為此時沒有promise,所以異步一下
try {//捕獲成功回呼的錯誤,丟給下一個then
let res=successCallback(this.value)
//獲取上一個then方法的回呼回傳值,并傳遞給下一個then的回呼
// resolve(res)//如果res不是promise物件,那就直接丟出去給下一個then,如果是一個promise物件,根據物件的狀態,獲取對應的值,然后丟出去
resolvePromise(promise2,res,resolve,reject)
} catch (error) {
reject(error)
}
},0)
}else if(this.status ===REJECTED){
setTimeout(()=>{//因為此時沒有promise,所以異步一下
try {//捕獲成功回呼的錯誤,丟給下一個then
let res=failCallback(this.value)
//獲取上一個then方法的回呼回傳值,并傳遞給下一個then的回呼
// resolve(res)//如果res不是promise物件,那就直接丟出去給下一個then,如果是一個promise物件,根據物件的狀態,獲取對應的值,然后丟出去
resolvePromise(promise2,res,resolve,reject)
} catch (error) {
reject(error)
}
},0)
}else{
//如果還是pending的情況
//說明是異步代碼
//先預存盤成功回呼和失敗回呼
this.successCallback=this.push(()=>{
// successCallback()
setTimeout(()=>{//因為此時沒有promise,所以異步一下
try {//捕獲成功回呼的錯誤,丟給下一個then
let res=successCallback(this.value)
//獲取上一個then方法的回呼回傳值,并傳遞給下一個then的回呼
// resolve(res)//如果res不是promise物件,那就直接丟出去給下一個then,如果是一個promise物件,根據物件的狀態,獲取對應的值,然后丟出去
resolvePromise(promise2,res,resolve,reject)
} catch (error) {
reject(error)
}
},0)
})
this.failCallback=this.push(()=>{
// failCallback()
setTimeout(()=>{//因為此時沒有promise,所以異步一下
try {//捕獲成功回呼的錯誤,丟給下一個then
let res=failCallback(this.value)
//獲取上一個then方法的回呼回傳值,并傳遞給下一個then的回呼
// resolve(res)//如果res不是promise物件,那就直接丟出去給下一個then,如果是一個promise物件,根據物件的狀態,獲取對應的值,然后丟出去
resolvePromise(promise2,res,resolve,reject)
} catch (error) {
reject(error)
}
},0)
})
}
})
return promise2
}
// all靜態方法,接收陣列,陣列的元素是promise或者普通元素,回傳值是一個全新的promise,呼叫then時的結果也是陣列,順序和傳入陣列的順序相同
static all(arr){
let res=[]
let num=0
return new Mypromise((resolve,reject)=>{
function add(index,value){
res[index]=value
num++
if(num===arr.length)resolve(res) //把結果丟出去
}
for(let i=0,i<arr.length,i++){
let current=arr[i]
if(current instanceof Mypromise){
//是個promise物件
current.then(value=>add(i,value),reason=>reject(reason))
}else{
//不是個promise物件,直接丟到結果陣列中
add(i,current)
}
}
})
}
// resolve方法,接受promise或者普通值
static resolve(value){
if(value instanceof Mypromise){
return value
}else{
return new Mypromise(resolve=>resolve(value))
}
}
//補上catch方法
catch(failCallback){
return this.then(undefined,failCallback)
}
// finally
// 不管狀態是什么,finally一定要執行一次
// 要回傳promise物件
finally(callback){
return this.then(value=>{
// callback()這樣就直接丟出去了,如果callback的回傳值是個異步,就有問題了
return Mypromise.resolve(callback()).then(()=>value)
// return value
},(reason)=>{
// callback()
// throw reason
return Mypromise.resolve(callback()).then(()=>{throw reason})
})
}
}
function resolvePromise(promise2,res,resolve,reject){
if(promise2===res){
return reject('自己回傳了自己')
}
//判斷res是不是promise物件
if(res instanceof Mypromise){//判斷res是不是MyPromise的一個實體
res.then(resolve,reject)
}else{
resolve(res)
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/281290.html
標籤:其他
上一篇:maven工程中遇到Can‘t find bundle for base name xxx, locale zh_CN錯誤
