1. 程式人生 > 其它 >分別用promise、generator、async方法,解決程式碼中出現的回撥地獄問題

分別用promise、generator、async方法,解決程式碼中出現的回撥地獄問題

技術標籤:面試題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)