js多个异步请求,按顺序执行next

在js里面,偶尔会遇见需要多个异步按照顺序执行请求,又不想多层嵌套,,这里和promise.all的区别在于,promise或者Jquery里面的$.when 是同时发送多个请求,一起返回,发出去的顺序是一起;这里是按照顺序发请求

方法 一 、首先创建一个迭代器,接收任意多个函数参数

function nextRegister(){
    var args = arguments;
    var count = 0;
    var comm = {};
    function nextTime(){
        count++;
        if(count < args.length){
            if(args[count] && Object.prototype.toString.call(args[count]) == '[object Function]'){
                args[count](comm,nextTime);
            }
        }
    }
    if(args[count] && Object.prototype.toString.call(args[count]) == '[object Function]'){
        args[count](comm,nextTime);
    }  
} 

创建多个异步的函数,注入到迭代器中

/*
 comm:多个函数,公用的变量
 next:调用下一个函数
 * */
function fn1(comm,next){
    console.log('1');
    comm.age = 20;
    next();
}
function fn2(comm,next){
    next();
    console.log('2');
    console.log(comm.age);
}
function fn3(comm,next){
    console.log('3');
}
 
//开始执行迭代
nextRegister(fn1,fn2,fn3);

在这里,fn1-fn3函数中,做异步操作,知道在异步成功的时候调用next()就可以继续执行下一个函数,同时可以将前面函数返回的结果,绑定在comm上,带到下一个函数中

方法 二、参考express 和 koa 的写法
1、es5写法

function Iterator(){
    this.middlewares = [];
}
 
Iterator.prototype.use = function(fn){
    this.middlewares.push(fn);
    return this;
}
 
Iterator.prototype.run = function(ctx){
    function createNext(middleware, oldNext) {
        return function(){
            middleware(ctx, oldNext)
        };
    }
    let len = this.middlewares.length;
    let next = function(){};
    for (let i = len - 1; i >= 0; i--) {
        let currentMiddleware = this.middlewares[i];
        next = createNext(currentMiddleware, next); //从后往前遍历,前面的闭包保存后面的 next
    }
    next();
}
 
var iterator = new Iterator();
iterator.use(function(ctx,next){
    //这里可以做一些异步操作,只需要成功后调用 next
    console.log("start:a");
    next();
    console.log("end:a");
});
 
iterator.use(function(ctx,next){
    console.log("start:b");
    next();
    console.log("end:b");
});
 
iterator.run();

2、es6 的 async 写法

class Iterator{
    constructor(){
        this.middlewares = [];
    }
    use(fn){
        this.middlewares.push(fn); //存入任务
        return this;
    }
    async run(ctx){
        function createNext(middleware, oldNext) {
            return async () => {
                await middleware(ctx, oldNext);
            }
        }
        let len = this.middlewares.length;
        let next = async () => {
            return Promise.resolve();
        };
        for (let i = len - 1; i >= 0; i--) {
            let currentMiddleware = this.middlewares[i];
            next = createNext(currentMiddleware, next);
        }
        await next();
    }
}
 
let app = new Iterator();
app.use(async (ctx,next)=>{
    console.log("start:a");
    await next();
    console.log("end:a");
});
 
app.use(async (ctx,next)=>{
    console.log("start:b");
    await next();
    console.log("end:b");
});
app.run();
原创文章 65 获赞 73 访问量 7742

猜你喜欢

转载自blog.csdn.net/qq_43592064/article/details/105638991