zoukankan      html  css  js  c++  java
  • 别再看Promise 了,尝试下自己用JS 封装实现任务队列。

    // 建议复制到编辑器里跑一下看看

    function Model(tasksProperties){ }
    
    Model.create = function(init) {
        function Model(taskProperties) {
            if (this instanceof Model) {
                this.__t = mixin({}, taskProperties);
                if (this.__init)
                    this.__init(this.__t);
            } else {
                Model.add.call(Model, ...arguments);
            }
        }
        Model.add = add;
        return Model;
    }
    Model.add = add;
    function add(method, ...tasks) {
        var proto = this.prototype;
        validateTasks(tasks);
        var cacheName = "__t_" + method;
        proto[cacheName] = proto[cacheName] || [];
        proto[cacheName] = proto[cacheName].concat(tasks);
    
        proto[method] = function(params, cb, progress) {
            var that = mixin({ params: params || {} }, this.__t);
            that.rootMethodName = method; //添加是调用方法的名字
            
               var self = this;
            that.model = self;
            if (arguments.length > 2) {
                that.progress = progress;
            }
            var after = self["__t_after"];
            series(self[cacheName], that, function(err, data) {
                that.data = data;
                if (after && after.length) {
                    series(after, that, complete);
                } else {
                    cb()
                }
            });
            return that;
        }
    }
    Model.prototype.after = after;
    
    function after(tasks) {
        tasks = [].slice.call(arguments, 0);
        var cacheName = "__t_after";
        var proto = this;
        proto[cacheName] = proto[cacheName] || [];
        proto[cacheName] = proto[cacheName].concat(tasks);
    }
    
    function validateTasks(tasks) {
        for (var k in tasks) {
            var t = typeof tasks[k];
            if (t != "string" && t != "function" && !Array.isArray(tasks[k])) {
                throw new Error("Task must String, Function or Array: " + tasks[k]);
            }
        }
    }
    
    
    
    function emptyFunction() {}
    
    function mixin(obj, source) {
        if (obj && source) {
            for (var key in source) {
                if(source.hasOwnProperty(key)){
                    obj[key] = source[key]
                }
            }
        }
        return obj;
    }
    Model.series = series;
    
    function series(tasks, that, callback, deepIndex) {
    
        callback = callback || emptyFunction;
    
        var completed = 0,
            len = tasks.length;
        if (!len) {
            return callback && callback();
        }
        deepIndex = deepIndex || 0;
        that.deepIndex = deepIndex;
        that.debug = that.debug || emptyFunction;
    
        function next(code, done) {
            if (code === undefined) {
                completed += 1;
            } else if (code === true) {
                return callback(that.error, that.data);
            } else if (code instanceof Error) {
                //Save error
                that.error = code;
                return callback(code);
            } else if (Array.isArray(code)) {
                //Call the next task list
                series(code, that, done ? done : function(err, data) {
                    next(err ? err : undefined);
                }, deepIndex + 1);
                return;
            } else if (typeof code == "number") {
                if (code < 0) {
                    code = len + code;
                }
                completed = code;
            } else if ((completed = tasks.indexOf(code)) == -1) {
                return callback(new Error("Unknown task for " + code));
            }
    
            if (completed >= len || completed < 0) {
                callback(that.error, that.data);
            } else {
                iterate();
            }
        }
    
        function iterate() {
            var task = tasks[completed];
    
            if (!len) {
                callback();
            } else if (typeof task == "string") {
                that.debug(deepIndex, task);
                next();
            } else if (task instanceof Function) {
                that.debug(deepIndex, task.name || "anonymous");
                if (!task.length) {
                    //has not next
                    next(task.call(that));
                } else {
                    task.call(that, next);
                }
            } else if (Array.isArray(task)) {
                next(task);
            } else {
                throw Error("Unsupported task type");
            }
        }
        iterate();
    }
    var model =  Model.create('init') //可传入function 或者 obj 初始化定义
    
    var requestApi = new model({ request: 'request', clearCookie: 'clearCookie', jsonError: true, os_type:'a'});
    
    function fn5(next){
        setTimeout(() => {
            console.log('第五个任务函数')
            next()
        }, 1500);
    }
    function fn6(next){
        setTimeout(() => {
            console.log('第六个任务函数')
            next()
        }, 1000);
    }
    function fn7(next){
        setTimeout(() => {
            console.log('第七个任务函数')
            next()
        }, 500);
    }
    tasks = [fn5,fn6,fn7]
    
    model('test',fn2,fn1,tasks,fn3,fn4)
    
    function fn1(next){
        setTimeout(() => {
            console.log('第一个任务函数')
            if(Math.random() > 0.3){
                console.log('穿插')
                next([fn6,fn7],function(){
                    console.log('中间穿插完成')
                    next()
                })
            }else{
                next()
            }
        }, 1000);
    }
    function fn2(next){
        setTimeout(() => {
            console.log('第二个任务函数')
            next()
        }, 1000);
    }
    function fn3(next){ 
        setTimeout(() => {
            console.log('第三个任务函数')
            next()
        }, 1000);
    }
    function fn4(next){
        setTimeout(() => {
            console.log('第四个任务函数')
            next()
        }, 1000);
    }
    
    requestApi.test({a:'1',b:'2'},function(){
        console.log('callback done')
    })
  • 相关阅读:
    token验证流程
    mongodb常用命令
    vue生命周期详解
    json-server基本使用
    Vue实现一个简单的todolist
    [高级软件工程教学]个人第2次作业第一次测评结果
    [福大高级软工教学]个人第1次作业成绩公布
    nginx+tomcat负载均衡
    apache 工作模式
    Apache主要的配置文件们
  • 原文地址:https://www.cnblogs.com/hjj2ldq/p/12531256.html
Copyright © 2011-2022 走看看