js 应用数组行列模仿多线程操纵

不知道下面的主意对不对,若有毛病还请大佬指正

需求剖析

有一批装备,数目许多,须要为他们开启长途驱动(即挪用背景的长途驱动接口),问题是背景处置惩罚长途驱动只能一台一台装备处置惩罚,如果装备数目许多,背景php 在30s 内处置惩罚不完就会 timeout

  • 最最先的方法,将所以装备一切交给背景,接口只要求一次,如许做的效果是,这个要求经常超时(不可用)
    由于背景没法一次处置惩罚这么多数据,所以要求超时

  • 第二种主意:将一切装备分组,比方 3个一组,然后轮回分组好的列表数组,在轮回内部用闭包举行接见要求
    如许做的效果是会有许多个ajax要求在同时举行,也没法取得一切要求完毕的时候的钩子

  • 第三种主意(我们老大的主意):模仿线程操纵,模仿同时开启多个线程,一切要求即装备列表放在一个线程池内(数组),每一个线程的事情,只有当本次事情完成后,才能够继承去线程池内去拿新使命(即发送新情求),如许就能够掌握同时要求的个数(线程数)以及要求完毕的时候的钩子。

代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
    <!-- 一个驱动效果(每一个线程的要求)及时显现的面板 -->
    <div id="drivepanel"></div>
</body>
<script src="http://libs.baidu.com/jquery/1.11.1/jquery.min.js"></script>
<script>
    
    /*
    *  参数列表: 驱动装备的列表数组,驱动时长    
    */

    var drivelist = [1,2,3,4,5,6,7,8,9,10];         // 待驱动的装备列表
    var drivetime = 5;                                // 驱动时长

    var dom = $("#drivepanel");
    // 取得底层函数 return 出的对象
    var runui = rundeviceui();
    //向底层函数传入须要显现的面板
    runui.init(dom);

    //启动函数
    runui.start(drivelist,drivetime,function(){
        //顺序运转中
        console.log('顺序运转中!');
    },function(){
        //顺序运转完毕
        console.log("顺序运转完毕!");
    })

    //驱动装备的底层函数
    function rundeviceui() {
        return {
            init:function(context){
                this.context = context;
                this.r_init();
                this.c_init();
            },
            list:[],          // 列表数组,线程池(列表中的每一项相当于一个使命)
            drivetime:0,      //驱动时长
            onrun:null,          //运转时函数
            onend:null,          //运转完毕时函数
            runnumber:3,      //同时开启的线程数目
            c_init:function(){      
                 //初始化一些操纵
            },
            r_init:function(){
                //绑定事宜操纵
            },
            start:function(list,drivetime,onrun,onend){   //启动函数
                var me = this;
                this.list = list;
                this.drivetime = drivetime;
                this.onrun = onrun;
                this.onend = onend;

                //开启面板显现
                this.context.show();

                this.run(me.runnumber,function(){
                    me.onend();
                })
            },
            run:function(number,onend){    //运转时函数
                var me = this;
                var runnow = 0;            //正在运转的线程数
                for(var i=0; i<number; i++){
                    runnow++;
                    setTimeout(_run);           //顺次开启事前设定好的线程(runnumber)
                }

        
                function _run(){
                    var data = me.list.shift();  //从线程池掏出的使命
                    if(!data){                  //如果线程池内没使命了,挪用完毕函数
                        _runend() 
                    }else{
                        console.log('run',data);
                        var selfFun = arguments.callee;    //当前函数
                        me.showStatus(data,'已提交处置惩罚!');

                        // 顺序运转中的钩子
                        me.onrun && me.onrun();

                        //挪用要求接口
                        me.ajaxFn(data,drivetime,function(){
                            var status = "处置惩罚胜利!";
                            me.showStatus(data,status);
                            setTimeout(selfFun);       //再次挪用本身
                        })

                    }
                }

                // 完毕函数
                // 当线程池内的使命处置惩罚完毕后,实行,_runend 函数,然后线程线程递减,当正在运转的线程数为 0 时挪用使命完成函数
                function _runend(){
                    runnow--; 
                    if(runnow <= 0){     
                        onend && onend();
                    }
                }
            },

            showStatus:function(devicecode,status){    //面板显现要求的及时状况
                var me = this;
                //建立列表dom 元素,用 devicecode 当作 name 值
                var dom = this.context.find("[name="+ devicecode +"]");
                if(dom.length <= 0){ 
                    //如果该 dom 元素不存在,则建立
                    dom = this.c_getrow(devicecode,status);
                }

                //如果该 dom 元素已存在,则为其附上 适宜的 status 值
                dom.html(devicecode + ":" + status);
            },

            c_getrow:function(devicecode,status){           //建立dom元素
                var me = this;
                var dom = $("<div></div>").attr('name',devicecode);
                this.context.append(dom);
                return dom;
            },

            //模仿背景的要求接口  
            ajaxFn:function(data,time,fn,fnerr){
                // 嗒嗒哒,,,发送ajax要求,要求失利暂不斟酌

                setTimeout(function(){
                    fn && fn();
                },3000);
            }
        }
    }

</script>
</html>
    原文作者:大桔子
    原文地址: https://segmentfault.com/a/1190000010336531
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞