分別用promise、generator、async方法,解決程式碼中出現的回撥地獄問題
阿新 • • 發佈:2020-12-19
技術標籤:面試題javascript
回撥地獄:
setTimeout(()=>{
console.log(1111)
setTimeout(()=>{
console.log(2222)
setTimeout(()=>{
console.log(3333)
},3000)
},2000)
},1000)
1、用Promise
function pro(data, time) { return new Promise(res => { setTimeout(() => { res(data) }, time * 1000) }) } pro(111, 1).then(res => { console.log(res) return pro(222, 2) }).then(res => { console.log(res) return pro(333, 3) }).then(res => { console.log(res) })
2、用async
async function run() {
console.log(await pro(111, 1))
console.log(await pro(222, 2))
console.log(await pro(333, 3))
}
run()
3、generator
這個是真的難想,這個屬於JS的套路問題,純generator來做,思路:
- 利用柯里化,儲存每次要執行的函式
- 在每次執行的函式中加入next,來通知下一次執行
- 本質上這裡的generate是強行在用,放到數組裡一樣能行
- 重要的是柯里化來儲存將要執行的函式和注入回撥的思路
function handleData(data, time, cb) { setTimeout(() => { console.log(data) cb() }, time * 1000) } function handleGen(gen) { const g = gen() const next = () => { let result = g.next() if(result.done) return result.value(next) } next() } var thunk = fn => (...args) => cb => { args.push(cb) fn(...args) } var f = thunk(handleData) function* gen() { yield f(111, 1) yield f(222, 2) yield f(333, 3) } handleGen(gen)