Javascript多执行绪+非同步应用动态载入大量元素到Dom
     /**
     *【jQuery】deferred物件介绍及使用deferred物件解决ajax非同步问题
     * https://www.gss.com.tw/blog/jquery%E9%80%9A%E9%81%8Edeferred%E7%89%A9%E4%BB%B6%E7%AE%A1%E7%90%86ajax%E9%9D%9E%E5%90%8C%E6%AD%A5
     */
    var deferred = $.Deferred(),
        deferred2 = $.Deferred(); 
    var isCircleClick = false;
    // Worker
    if (window.Worker) {        
        var all = data.allGraph.length;
        var curt = 0;
        var loadingMsg = $("app-loading span").text();
        /********************** multithread go go go **********************/
        var numWorkers = 10;//执行绪数量
        var workers = [];
        var chunkCount = Math.floor(all / numWorkers);//整数除法
        var deferred3s = [];//JQuery的非同步物件阵列
        console.log(`[svgDraw] start time [thread count:${numWorkers}] => ${new Date()}`);
        for (var i = 0; i < numWorkers; i++)
        {
            if (i == numWorkers - 1)
            {//最后一个执行绪把余数全部处理掉
                var modValue = all % numWorkers;
                if (modValue > 0)
                {
                    chunkCount += modValue;
                }                
            }
            var chunkData = data.allGraph.splice(0, chunkCount);            
            /*
                new Worker('assets/localhost_env_js/drawPCBWorker.js');//本机worker.js
                new Worker('../Areas/Viewer/Scripts/drawPCBWorker.js');//uat worker.js
            */
            var drawWorker = new Worker(drawPCBWorkerUrl);//宣告新执行绪,drawPCBWorkerUrl为执行绪要执行的工作流程.js                    
            workers.push(drawWorker);
            var deferred3 = $.Deferred();//建立JQuery非同步物件
            deferred3s.push(deferred3);
            //执行执行绪工作流程
            drawWorker.postMessage([chunkData, basicStrokeWidth]);
            (function (i, deferred3) {
	            //接收执行绪工作流程的回传
                drawWorker.onmessage = function (e) {
                    for (var i = 0; i < e.data.length; i++) {
                        /*
                         *错误範例!!!!!
                         *绝对不能+=1这样累计,会严重拖累迴圈效能!!!!!      
                        //curt += 1;	
                        //$("app-loading span").html(`${loadingMsg}${curt}/${all}`)
                        */
                        var combinGroup = myDocument.createElementNS(svgNS, "g");
                        setAttributes(combinGroup, {
                            "id": e.data[i].refdes,
                            "stroke": (e.data[i].PN == "" ? getLevelData("REFDES", "NOASSEMBLED").ColorCode : getLevelData(e.data[i].mainClass, e.data[i].subClass).ColorCode),
                            "class": e.data[i].mainClass + " " + e.data[i].subClass + (e.data[i].PN == "" ? " NOASSEMBLED" : ""),
                            "style": getLevelData(e.data[i].mainClass, e.data[i].subClass).Display == true ? 'display:inline;' : 'display: none;',
                            "bom": (e.data[i].mainClass != "VIA" ? e.data[i].Bom : ""),
                            "partnumber": (e.data[i].mainClass != "VIA" ? e.data[i].PN : ""),
                            "data-val": e.data[i]["data-val"],
                            "bWidth": e.data[i].bWidth,
                            "bHeight": e.data[i].bHeight,
                            "notice": e.data[i].notice ? e.data[i].notice : ""
                        });
                        if (e.data[i].mainClass === "VIA") {
                            combinGroup.setAttribute("data-test", e.data[i].isTestVia);
                            if (e.data[i].isTestVia !== undefined && e.data[i].isTestVia === false && my.showAllVia === false) {
                                combinGroup.setAttribute("class", combinGroup.getAttribute("class") + " none");
                            }
                        }
                        for (var j = 0; j < e.data[i].items.length; j++) {
                            for (var graph in e.data[i].items[j]) {
                                var dom = myDocument.createElementNS(svgNS, graph)
                                setAttributes(dom, e.data[i].items[j][graph]);
                                if (graph === "circle") {
                                    var circle = dom;
                                    circle.addEventListener("mousedown", function (e) {
                                        isCircleClick = true;
                                    });
                                    circle.addEventListener("dblclick", function (e) {
                                        getNetLineData(this.getAttribute("net"));
                                    }, false);
                                }
                                combinGroup.appendChild(dom);                                
                            }
                        }
                        group.appendChild(combinGroup);
                    }
                    
                    curt += e.data.length;
                    $("app-loading span").html(`${loadingMsg}${curt}/${all}`)
                    deferred3.resolve();
                }
            })(i, deferred3);
        }        
        $.when.apply($, deferred3s).done(function () {
            //等待所有JQuery非同步物件都完成工作
            deferred.resolve();
            console.log(`[svgDraw] end time => ${new Date()}`);
        });
        /********************** multithread end **********************/
    }
ChatGPT範例
Qestion:javascript es3 多执行绪搭配jquery deferred如何使用
在 JavaScript ES3 环境中,无法直接使用现代 JavaScript 特性(例如 let 和 const),但可以通过 Web Workers 实现多线程,并使用 jQuery Deferred 来管理异步操作。以下是一个示例,展示如何在 ES3 环境中使用 Web Workers 和 jQuery Deferred 进行多线程处理:
示例代码
Web Worker 文件 (worker.js)
javascript
self.onmessage = function(event) {
    var data = event.data;
    var result = 0;
    // 假设进行一些计算,这里仅做示范
    for (var i = data.start; i < data.end; i++) {
        result += i;
    }
    // 将结果发送回主线程
    self.postMessage(result);
};
主线程代码 (main.js)
javascript
$(document).ready(function() {
    var numWorkers = 10;
    var totalIterations = 100000;
    var iterationsPerWorker = totalIterations / numWorkers;
    var workers = [];
    var deferreds = [];
    var results = [];
    var i;
    // 创建 Web Workers 并分配任务
    for (i = 0; i < numWorkers; i++) {
        var worker = new Worker('worker.js');
        workers.push(worker);
        var deferred = $.Deferred();
        deferreds.push(deferred);
        worker.postMessage({ start: i * iterationsPerWorker, end: (i + 1) * iterationsPerWorker });
        (function(i, deferred) {
            worker.onmessage = function(event) {
                results[i] = event.data;
                deferred.resolve();
            };
        })(i, deferred);
    }
    // 使用 $.when.apply 方法处理 Deferred 数组
    $.when.apply($, deferreds).done(function() {
        var totalResult = 0;
        for (i = 0; i < results.length; i++) {
            totalResult += results[i];
        }
        console.log('All workers have completed their tasks.');
        console.log('Total result:', totalResult);
    });
});
解释
Web Worker 文件 (worker.js):
self.onmessage:处理从主线程接收到的消息。- 在接收到消息后执行计算,然后使用 
self.postMessage将结果发送回主线程。 
主线程代码 (main.js):
- 创建 10 个 Web Workers,每个 Worker 处理总循环的一部分。
 - 使用 
$.Deferred()创建 Deferred 对象,并将它们添加到deferreds数组中。 - 使用 
postMessage将循环范围分配给每个 Worker,并在 Worker 完成任务后解决对应的 Deferred。 - 使用 
$.when.apply($, deferreds).done等待所有 Deferred 对象完成,然后计算总结果并输出。 
通过这种方式,您可以使用 Web Workers 实现多线程处理,并使用 jQuery Deferred 来管理异步操作和回调。这种方法在需要处理大量数据或执行复杂计算的情况下,可以提高性能。

	    	微信扫一扫打赏
	    
	    	支付宝扫一扫打赏