同步队列和异步队列

3,715 阅读1分钟

在很多源码的框架中,会经常看到队列的实现,例如:js异步队列,vue生命周期,koa模型,webpack中plugins等

一.同步队列

同步队列很简单,通过for循环遍历就行了

let queue= []
...执行其他操作
queue.push(fn1)
...执行其他操作
queue.push(fn2)
...执行其他操作
queue.push(fn3)
...收集完成
function runQueue(){
    for(let i=0;i<arr.length;i++){
        arr[i]() 
    }
}

runQueue()

二.异步队列

1. 通过注入next,决定什么时候执行队列下一方法

let queue= []
queue.push(function(next){
    setTimeout(()=>{
        next()  //异步后调用下一个队列
    },1000)
})

要实现这样的逻辑,需要把next方法暴露给用户,什么时候执行由用户决定

执行异步队列实现,如下:

function runQueue(queue,i, cb){
    if(i<queue.length){
        if(queue[i]){
            queue[i](function next(){   //next函数暴露给用户
                   runQueue(queue,i+1,cb)   
            })
        }else{
            runQueue(queue,i+1,cb)        
        }
    }else{
        cb()
    }
}
runQueue(queue,0,cb)

2.promise函数自动执行next

如果push到队列中的函数返回的是promise,我们希望在resolve的时候,自动执行next

function runPromiseQueue(queue, i, cb) {
            if (i < queue.length) {
                if (queue[i]) {
                    let res = queue[i]()
                    if (res instanceof Promise) {
                        res.then(function next(args) {
                            runPromiseQueue(queue, i + 1,cb)
                            return args
                        })
                    } else {
                        runPromiseQueue(queue, i + 1,cb)
                    }
                } else {
                    next(i + 1)
                }
            } else {
                cb()
            }
        }

为什么promise.then就能实现上面的这个方案

promise.then其实内部原理也是同过调用then方法往promise中resolvedQueue队列中push待执行的方法,resolvedQueue队列的执行时机是在执行resolve函数的时候,所以通过控制resolve方法的执行也就间接手动执行next的方法

promise源码实现:juejin.cn/post/684490…