浅析生成器+promise实现的run函数

199 阅读3分钟

“Offer 驾到,掘友接招!我正在参与2022春招打卡活动,点击查看活动详情。”

近期阅读了《你不知道的js》(中卷),细细阅读了生成器和迭代器的一章,收获不少,也看到了大神写的代码有多美妙,故此来浅析一下使用生成器+promise实现的run函数,其实就是我们平时用到的async和await的代码实现。

run函数实现

先附上《你不知道的js》(中卷)中的run函数的实现

function run (gen) {
    var args = [].slice.call(arguments, 1), it;
    it = gen.apply(this, args)
    return Promise.resolve().then(function handleNext(value){
        var next = it.next(value)
        return (function handleResult(next) {
            if(next.done){
                return next.value;
            }
            else{
             return Promsie.resolve(next.value).then(handleNext, function handleError(err){
                return Promise.resolve(it.throw(err)).then(handleResult)
                })
            }
        })(next)
    })
}

浅析run代码

run

run函数主要干了什么:

  1. 迭代器的自动迭代
  2. 返回一个promise
  3. 实现迭代器的有序迭代

handleNext

handleNext函数主要干了什么:

  1. 执行迭代器的next方法进行迭代
  2. 传入next,调用handleResult函数

handleResult

handleResult函数主要干了什么:

  1. 判断迭代器是否迭代完成
  2. 若迭代器迭代完成,返回迭代器的value值
  3. 若迭代器未迭代完成,返回一个promise使用then方法,传入handleNext继续进行迭代

看async\await

平时我就了解到:

  1. async函数返回一个promise
  2. await要在async函数中使用
  3. 要await一个Promise 现在看来,await和async大概对应如下:

await ---> yield

async ---> 将函数当作gen传入run中

【注】 要await一个成功状态的promise,才会实现代码的有序执行

关键点:

  1. 若在Promise.resolve()中传入promise,则等待传入promise决议后再决议Promise.resolve返回的promise
  2. 若在then中的onResolved中返回一个promise,则等待onResolved返回的promise决议后,决议then返回的promise 其实上述关键点只是一点,是利用了resolvePromise决议promise的规则
// 根据传入的x值使用不同的规则来决定返回的promsie2的状态
resolvePromise(x, promise2, resolve, reject){
...
// 若x值是promise对象
if (x instanceof Promise){
    if(x.status === 'pedding'){
        x.then(y => {
            this.resolvePromise(y, promise2, resolve, reject)
        }, reject)
    }else{
        x.then(resolve, reject)
    }
}
...
}

利用resolvePromise中的决议promise状态的规则,来实现代码的有序执行

在这里认识到,学习好promise是多么的重要!!!

提一嘴promise

对于promise在这里稍微提一嘴:

一、Promsie对于代码的有序执行是利用Promsie.status状态:

在Promsie.status状态pedding ---> fulfilled时,才按照注册顺序执行onResolved;在Promsie.status状态pedding ---> rejected时,才按照注册顺序执行onRejected。

故将你想要后面执行的代码放在then中

二、Promise的状态

  1. 在创建Promsie时,是根据你传入的constructor函数中,何时调用resolve/reject来决议创建的Promsie状态
  2. 在后续then返回的Promsie中,是根据onResolved/onRejected的返回值,进行resolvedPromise来决议then返回的Promsie的状态 ______(排除了执行错误的情况)

以上内容都是自我的总结理解,有什么错误欢迎指正❀❀❀