Generator函数自执行

2021-09-18  本文已影响0人  Small_Song

本文的目的是解决异步执行的顺序

1. 有了async await就可以控制异步执行的顺序,为什么还需要generator函数,generator看起来使用更麻烦

答:async await函数只能控制基于peomise的异步的顺序,对于非基于promise的异步,并不能起到控制顺序的作用,而generator可以做到

2. 把普通函数也转换成promise函数,不就可以用async await了吗

答:带有回调钩子的函数确实可以转换成promise,虽然麻烦点,但还是可行,问题是,有些异步就不带回调钩子,比如antd form里面的form.setFieldsValue(), form.resetFields()等等可以转成promise吗,反正我目前水平是做不到。

let fun2 = async() => {
    await setTimeout(() => {console.log(5)}, 5000)
    await setTimeout(() => {console.log(3)}, 3000)
    await setTimeout(() => {console.log(1)}, 1000)
}
fun2()

// 打印如下:
// 1
// 3
// 5
function* fun3 () {
    yield setTimeout(() => {console.log(5)}, 5000)
    yield setTimeout(() => {console.log(3)}, 3000)
    yield setTimeout(() => {console.log(1)}, 1000)
}
let g = fun3()
g.next()
// {value: 18654, done: false}
// 5
g.next()
// {value: 18933, done: false}
// 3
g.next()
// {value: 19120, done: false}
// 1

现在用generator函数,问题是解决了,但是每次都要手动调用这么多次next吗,有没有更好的办法呢

2. co函数:自动执行generator函数

let i = 0
function getNumber(){
    return new Promise((resolve,reject) => {
        setTimeout(() => {
            resolve(++i)
        },1000)
    })
}

function *read(){
    let a = yield getNumber();
    console.log(a)
    let b = yield 'b'
    console.log(b)
    let c = yield getNumber();
    console.log(c)
}

function co(gen){
    return new Promise((resolve, reject) => {
        let g = gen()
        function next(lastValue){
            let { value, done } = g.next(lastValue)
            if(done){
                resolve(lastValue)
            } else {
                if(value instanceof Promise){
                    value.then(next,err => reject(err))
                } else {
                     next(value)
                }
            }
        }
        next()
    })
}
co(read).then((data) => {
    console.log(data)
},(reason) => {
    console.log(reason)
})

3. co库

npm库里面自己找一下

上一篇下一篇

猜你喜欢

热点阅读