該Promise的實現,只解決非同步巢狀的問題,並沒有其他All之類的方法哦。
一、類的定義階段
class Pro {
constructor (fn) {
this.arr = []
this.count = -1
fn(this)
}
then (r) {
if (typeof (r) === `function`) {
this.arr.push(r)
return this
} else {
this.arr[++this.count] && this.arr[this.count](this, r)
}
}
}
複製程式碼
該程式碼只有15行左右,要再短點也不是不可,但越短的程式碼只有兩種可能,要麼easy,要麼difficulty,該類應該算是前者,再配合debugger還是比較容易看得懂的。
二、呼叫階段
new Pro(fn => {
setTimeout(() => {
let data = 1 // 舉例資料為1
console.log(`A拿到資料後,進行處理`, data)
console.log(`A將資料傳到下一個ajax`)
console.log(`A-------------`)
fn.then(data)
}, 500)
}).then((fn, r) => {
console.log(`A上一個資料是`, r)
setTimeout(() => {
let data = 2
console.log(`A拿到資料後,進行處理`, data)
console.log(`A將資料傳到下一個ajax`)
console.log(`A-------------`)
fn.then(data)
}, 500)
}).then((fn, r) => {
console.log(`A上一個資料是`, r)
setTimeout(() => {
let data = 3
console.log(`A拿到資料後,進行處理`, data)
console.log(`A將資料傳到下一個ajax`)
console.log(`A-------------`)
fn.then(data)
}, 500)
}).then((fn, r) => {
console.log(`A上一個資料是`, r)
setTimeout(() => {
let data = 4
console.log(`A拿到資料後,進行處理`, data)
}, 500)
})
複製程式碼
以下是返回的結果
這裡就達到了巢狀的目的,並且程式碼上沒有難看的階梯狀結構。
三、多非同步呼叫檢測
new Pro(fn => {
setTimeout(() => {
let data = 1 // 舉例資料為1
console.log(`A拿到資料後,進行處理`, data)
console.log(`A將資料傳到下一個ajax`)
console.log(`A-------------`)
fn.then(data)
}, 500)
}).then((fn, r) => {
console.log(`A上一個資料是`, r)
setTimeout(() => {
let data = 2
console.log(`A拿到資料後,進行處理`, data)
console.log(`A將資料傳到下一個ajax`)
console.log(`A-------------`)
fn.then(data)
}, 500)
}).then((fn, r) => {
console.log(`A上一個資料是`, r)
setTimeout(() => {
let data = 3
console.log(`A拿到資料後,進行處理`, data)
console.log(`A將資料傳到下一個ajax`)
console.log(`A-------------`)
fn.then(data)
}, 500)
}).then((fn, r) => {
console.log(`A上一個資料是`, r)
setTimeout(() => {
let data = 4
console.log(`A拿到資料後,進行處理`, data)
}, 500)
})
new Pro(fn => {
setTimeout(() => {
let data = 11
console.log(`B拿到資料後,進行處理`, data)
console.log(`B將資料傳到下一個ajax`)
console.log(`B-------------`)
fn.then(data)
}, 500)
}).then((fn, r) => {
console.log(`B上一個資料是`, r)
setTimeout(() => {
let data = 22
console.log(`B拿到資料後,進行處理`, data)
console.log(`B將資料傳到下一個ajax`)
console.log(`B-------------`)
fn.then(data)
}, 500)
}).then((fn, r) => {
console.log(`B上一個資料是`, r)
setTimeout(() => {
let data = 33
console.log(`B拿到資料後,進行處理`, data)
console.log(`B將資料傳到下一個ajax`)
console.log(`B-------------`)
fn.then(data)
}, 500)
}).then((fn, r) => {
console.log(`B上一個資料是`, r)
setTimeout(() => {
let data = 44
console.log(`B拿到資料後,進行處理`, data)
}, 500)
})
複製程式碼
以下是返回的結果
返回成功,A為A的呼叫棧,B為B的呼叫棧,沒有互相混淆。
關於
make:o︻そ╆OVE▅▅▅▆▇◤(清一色天空)
blog:http://blog.csdn.net/mcky_love
掘金:https://juejin.im/user/59fbe6c66fb9a045186a159a/posts
結束語
成功之後,即可對該類進行二次封裝,如工廠模式下,以return物件來實現Promise.all()等方法。所有的實現原理並不一定要以原始碼來實現,萬一你有更好的思路呢?(∩_∩)