前言:
虽然html5中已经提供Worker对象进行多线程的支持,可该对象在某些场合还是无法满足需求——因为它难以操作DOM元素。
而某些情况下,进行大量的js计算以及DOM元素调用的情况下,会出现脚本执行时间过长,被浏览器强制中断的情况。
顾本人整合了该多线程伪类,分享给各位。
正文:
1、设计思路
方法模块化,一个大的需要长时间执行的进程切分成多个小进程,添加入执行队列中,由该队列进行管理,执行这些方法。
2、源代码
/* 伪线程类 author: JeremyWang */ function Threading(timestamp) { //#region 成员对象 var _t, //线程定时器 _tempTime = 0, //线程已执行时间 _timestamp = 15, //线程最多一次执行时间15ms _waitTime = 1, //线程执行一次后休息时间1ms _waitTimeTemp = 100, //线程未运行时休息时间100ms _state = false, //线程状态 _methodArray = []; //线程管理 //#endregion //#region 构造函数 if (timestamp) { setTimestamp (timestamp); } //#endregion //#region 成员属性 this.setTimestamp = function (value) { _timestamp = value; }; this.setWaitTime = function (value) { _waitTime = value; }; this.getMethodCount = function () { return _methodArray.length; }; //#endregion //#region 成员方法 this.addMethod = function (fun, arg, callback) {//添加方法到队列 var method = { fun: fun, arg: arg, callback: callback }; _methodArray.push(method); }; this.start = function () {//开始线程 _state = true; threadDoing(); }; this.end = function () {//结束线程 clearTimeout(_t); _state = false; }; var threadDoing = function () { if (_state) { if (_methodArray.length > 0) { if (_tempTime < _timestamp) { var mm = new Date().getTime(); var method = _methodArray.splice(0, 1)[0]; //移除队列 execMethod(method); //执行命令 var gap = (new Date().getTime() - mm) || 1; //至少一毫秒 _tempTime += gap; //继续执行 threadDoing(); } else { //休息 _tempTime = 0; _t = setTimeout(threadDoing, _waitTime); } } else { //长休息 _tempTime = 0; _t = setTimeout(threadDoing, _waitTimeTemp); } } }; var execMethod = function (method) { var result = method.fun(method.arg); if (method.callback) { method.callback(result); } }; //#endregion }
3、使用方法
var thread = new Threading(); //伪线程 thread.start(); //测试数据 var arrObj = []; var callback = function (result) { console.log(result); }; //向线程队列中添加方法 var count = 1000; while (count--) { thread.addMethod(function (defultItem) { arrObj.push(defultItem); return arrObj.length; }, count + 1, callback); }