现在的位置: 首页 > web前端 > 正文

怎么使用Promise.resolve

2020年07月06日 web前端 ⁄ 共 1215字 ⁄ 字号 评论关闭

  当第一个中间件即dispatch(0)的next()调用时,此时应该是执行dispatch(1),在执行到下面这个判断的时候,if(i<=index)returnPromise.reject(newError('next()calledmultipletimes'))此时的index的值是0,而i的值是1,不满足i<=index这个条件,继续执行下面的index=i的赋值,此时index的值为1。但是如果第一个中间件内部又多执行了一次next()的话,此时又会执行dispatch(2)。上面说到,同一个中间件内的i的值是不变的,所以此时i的值依然是1,所以导致了i<=index的情况。


  为什么使用Promise.resolve()包一层


  可能会有人有疑问?既然async本身返回的就是Promise,为什么还要在使用Promise.resolve()包一层呢。这是为了兼容普通函数,使得普通函数也能正常使用。


  再回到中间件的执行机制,来看看具体是怎么回事。


  我们知道async的执行机制是:只有当所有的await异步都执行完之后才能返回一个Promise。所以当我们用async的语法写中间件的时候,执行流程大致如下:


  中间件返回Promise之后怎么办


  先执行第一个中间件(因为compose会默认执行dispatch(0)),该中间件返回Promise,然后被Koa监听,执行对应的逻辑(成功或失败)


  在执行第一个中间件的逻辑时,遇到awaitnext()时,会继续执行dispatch(i+1),也就是执行dispatch(1),会手动触发执行第二个中间件。这时候,第一个中间件awaitnext()后面的代码就会被pending,等待awaitnext()返回Promise,才会继续执行第一个中间件awaitnext()后面的代码。


  同样的在执行第二个中间件的时候,遇到awaitnext()的时候,会手动执行第三个中间件,awaitnext()后面的代码依然被pending,等待await下一个中间件的Promise.resolve。只有在接收到第三个中间件的resolve后才会执行后面的代码,然后第二个中间会返回Promise,被第一个中间件的await捕获,这时候才会执行第一个中间件的后续代码,然后再返回Promise


  以此类推,如果有多个中间件的时候,会依照上面的逻辑不断执行,先执行第一个中间件,在awaitnext()出pending,继续执行第二个中间件,继续在awaitnext()出pending,继续执行第三个中间,直到最后一个中间件执行完,然后返回Promise,然后倒数第二个中间件才执行后续的代码并返回Promise,然后是倒数第三个中间件。


   总之,中间件一直以这种方式执行直到第一个中间件执行完,并返回Promise,从而实现文章开头那张图的执行顺序。

抱歉!评论已关闭.