JS如何实现一个异步队列来按顺序执行函数?

发布于 2022-09-02 20:26:13 字数 102 浏览 13 评论 0

asyn([func1, func2, func3], function(){
    // func1,func2,func3全部按顺序执行完的回调
})

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

私藏温柔 2022-09-09 20:26:13

https://github.com/caolan/async#waterfall 比较符合

async.waterfall([
    function(callback) {
        callback(null, 'one', 'two');
    },
    function(arg1, arg2, callback) {
      // arg1 now equals 'one' and arg2 now equals 'two'
        callback(null, 'three');
    },
    function(arg1, callback) {
        // arg1 now equals 'three'
        callback(null, 'done');
    }
], function (err, result) {
    // result now equals 'done'
});
痴意少年 2022-09-09 20:26:13
function asyn(funsArray,resultCallback){
    var funExecResult=[];
    var executor=(function(){
        var index=0;
        return {
            next:function(){
                if(index< funsArray.length){
                    return funsArray[index++];
                }else{
                    return null;
                }
            }
        }
    }());

    (function doNext(){
        var nextFun=executor.next();
        if(nextFun){
            funExecResult.push(nextFun.call(null));
            doNext();
        }else{
            resultCallback.apply(null, funExecResult);
        }
    }());
    
}
迷途知返 2022-09-09 20:26:13

我这里假设你的这几个func都是能够返回Promise的异步函数,然后我们来写一个asyn方法:

var asyn = function(arr, cb) {
    arr
        .reduce((p, func) => p.then(func), Promise.resolve())
        .then(cb);
};

现在来测试一下:

var func1 = function() {
    return new Promise(function(resolve) {
        setTimeout(function() {
            console.log('func1');
            resolve();
        }, 500);
    });
};
var func2 = function() {
    return new Promise(function(resolve) {
        setTimeout(function() {
            console.log('func2');
            resolve();
        }, 300);
    });
};
var func3 = function() {
    return new Promise(function(resolve) {
        setTimeout(function() {
            console.log('func3');
            resolve();
        }, 100);
    });
};

asyn([func1, func2, func3], function() {
    console.log('all things gets done');
});
//func1
//func2
//func3
//all things gets done
人事已非 2022-09-09 20:26:13

Promise 大法好!

var funcs = [func1, func2, func3];
var funcPromise = funcs.map(function(func, i) {
    return new Promise(function(resolve) {
        func();
        console.log('func'+(i+1)+' well done!');
        resolve();  //如果 func 是异步方法的话需要把 resolve 定义到方法的 callback 中
    });
});
Promise.all(funcPromise).then(function() {
    console.log('all well done');
});

更爽一点可以直接用 async/await


var funcs = [func1, func2, func3];
(async () => {
    for(let i=0;i<funcs.length;i++) {
        await funcs[i]();
        console.log('func'+(i+1)+' well done');
    }
    console.log('all well done');
})()
奶茶白久 2022-09-09 20:26:13

简单实现的顺序执行,和并行执行的工具类
使用方法

var ac = AsyncCaller();
ac.pushQueue(asyncFunc1,args);
ac.pushQueue(asyncFunc2,args);
ac.exec(function(){
    console.log('tasks finished');
});

function asyncFunc1(){
    ajax.get(url,function(){
        dealWithComponentConfig.resolve(ac);
    })
}
function asyncFunc2(){
    ajax.post(url,function(){
        dealWithComponentConfig.resolve(ac);
    })
}
function AsyncCaller(){
    var allTasksPool = [];
    var queueTasksPool = [];
    Function.prototype.resolve = function(ac){
        ac.aysncFunRunOver.call(ac, this);
    };
    this.pushAll = function(asyncFunc,arguArr){
        if(queueTasksPool.length === 0){
            var funcObj = {'func':asyncFunc,'argu':arguArr};
            allTasksPool.push(funcObj);
        }else {
            console.error(errorMsg);
        }
        return this;
    };
    this.pushQueue = function(asyncFunc,arguArr){
        if(allTasksPool.length === 0){
            var funcObj = {'func':asyncFunc,'argu':arguArr};
            queueTasksPool.push(funcObj);
        }else{
            console.error(errorMsg);
        }
        return this;
    };

    this.aysncFunRunOver = function(caller){
        if(execType === "queue"){
            if(queueTasksPool.length === 0){
                if(this.finalFunc){
                    //delete Function.prototype.resolve;
                    this.finalFunc();
                }
            }else{
                var funcObj = queueTasksPool[0];
                queueTasksPool.shift();
                funcObj.func.apply(this,funcObj.argu);

            }
        }else if(execType === "all"){
            for (var i = 0; i < allTasksPool.length; i++) {
                var task = allTasksPool[i];
                if(caller === task.func){
                    allTasksPool.splice(i,1);
                    break;
                }
            }
            if(allTasksPool.length === 0){
                if(this.finalFunc){
                    //delete Function.prototype.resolve;
                    this.finalFunc();
                }
            }
        }
    };
    var execType = "queue";
    this.exec = function(callback){
        this.finalFunc = callback;
        if(allTasksPool.length > 0){
            execType = "all";
            executeAll();
        }else if(queueTasksPool.length > 0){
            execType = "queue";
            executeQueue();
        }else{
            this.finalFunc.call();
        }

    };
    function executeQueue(){
        var funcObj = queueTasksPool[0];
        queueTasksPool.shift();
        funcObj.func.apply(null,funcObj.argu);

    }
    function executeAll(){
        for(var i=0;i<allTasksPool.length;i++){
            var funcObj = allTasksPool[i];
            funcObj.func.apply(null,funcObj.argu);
        }
    }
    var errorMsg = "Only one type of task can be executed at same time";
}
药祭#氼 2022-09-09 20:26:13

// simple waterfall

function exec(tasks, finalcall) {
  return function _exec(index, task) {
    return (task = tasks[+index]) ? task(function () {
      _exec(++index)
    }) : finalcall();
  }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文