同时运行两个JS网络工作者:一个卡住了

时间:2016-07-21 20:52:43

标签: javascript php ajax multithreading web-worker

我正在开发一个封闭的系统网络应用程序,以帮助公司进行日常的在线商务活动。这意味着一方面它不会向公众开放,另一方面:它必须处理大量数据,同时保持流畅的工作经验。

这就是为什么我转向JS中的Web worker来在后台运行各种数据库访问和数据加载。 我的理解是,不仅主要的UI /主要JS不会中断,而且不同的网络工作者也会在不相互阻碍的情况下运行。

我现在有以下设置:

mainJS :在pageload上运行的函数statusCheck:

function statusCheck() {
    if(typeof(w__statusCheck) == "undefined") {
        var w__statusCheck = new Worker("...statusCheck.js");
        w__statusCheck.postMessage("go");
        w__statusCheck.onmessage = function(e) {
            var message = JSON.parse(e.data);
            if(message.text!=undefined) displayMessage(message.text);
        }
}

statusCheck.js 这个工作人员就是这样:

function checkStatus() {
        console.log("statusCheck started");
        // I will leave standard parts out:
            // creating and testing the ajax variable against different browsers

        ajaxRequest.onreadystatechange = function() {
            if(ajaxRequest.readyState == 4) {
                self.postMessage(ajaxRequest.responseText);

                var timer;
                timer = self.setTimeout(function(){
                    checkStatus();
                }, 1000);
            }
        }

        ajaxRequest.open("GET", "...worker_statusCheck.php", true);
        ajaxRequest.send(null);
    }

    this.onmessage = function(e){
        checkStatus();
    };

正如您所看到的,这会每秒重启(现在)。生产中的间隔可能会更长。 worker_statusCheck.php只是从数据库中获取不同的东西,并将它们编织成一个JSON对象,从而为我提供系统状态。

这很有效。

现在我有另一个工作者应该通过点击链接来启动,以有效地调用一些php来执行操作: mainJS loadWorker

function loadWorker(url="") {
    console.log("loadWorker started");

    if(url!="") {
        var uniqueID = "XXX" // creating a random ID based on timestamp and Math.random()

    if(typeof(window[uniqueID]) == "undefined") {
        var variables = { ajaxURL: url };
        window[uniqueID] = new Worker("....loadWorker.js");
        window[uniqueID].postMessage(JSON.stringify(variables));
        window[uniqueID].onmessage = function(e) {
            var message = JSON.parse(e.data);
            if(message["success"]!=undefined) {
                variables["close"] = "yes";
                window[uniqueID].postMessage(JSON.stringify(variables));
            }
        }
}

每次点击某个链接都会被调用,创建一个唯一命名的工作者,运行它,接收数据并告诉工作人员close()

php再次完成它的事情,并在漫长的过程的每一步之后在DB中写入进度更新。我使用上述重复statusCheck从DB获取这些进度更新。

现在,我可以看到数据库中的条目带有时间戳,所以我知道他们每次都会写入。 因此,两个工人都可以完成工作并可靠地运行。但我注意到,每当我启动手册(随机命名)工作程序时,statusCheck实际上都会停止执行。它只是卡住了...我能够通过两个工人的控制台输出确认这一点。因此,主要的JS似乎不会被卡住,但是statusCheck实际上会暂停...并在loadWorker完成时恢复。

我错过了一些基本的东西吗?任何见解都会受到赞赏,因为我不熟悉这个网络工作者的概念。

Thanx:)

2 个答案:

答案 0 :(得分:0)

你的问题缺乏真正弄清楚究竟出了什么问题的资源。我可以同意two web workers can operate at the same time,即使是同步操作。我为for个循环测试了这个并同步了XHR请求。

我会推荐多种方法。

首先 - 除非您使用一些CPU繁重的算法处理数据,否则Web工作人员会浪费时间。 XHR请求不会阻止主线程(除非您明确要求它们)。

  1. statusCheck()中,您声明var w__statusCheck,这意味着一个局部变量。因此,从外部范围看,它将始终为null。一旦代码在工作程序中运行,它可能会被垃圾收集。
  2. 请勿使用XMLHttpRequest.onreadystatechange。使用onloadonerror
  3. 变量的随机唯一ID几乎总是错误的。如果你需要存储worker refference,要么给它一个合理的名字(例如它应该加载的url)或者使用增量id。
  4. 发布给网络工作者的 NOT stringify数据。它已经由浏览器为您完成,可能以更优化的方式。将数据转换为某些东西是人们对网络工作者做的最常见的愚蠢行为。
  5. 同样在发布问题时,至少要确保代码有意义。在您的帖子中,花括号不匹配。

答案 1 :(得分:-1)

好吧..我弄清楚了: 我正在寻找所有错误的地方。事实证明,我已经在所有由工作人员调用的php脚本中初始化了我的php会话。我的两个平行工人都叫了一个。所以会话文件被第一个php脚本锁定,第二个必须等到它再次打开。这不是工人或JS被阻碍,而是php。

我现在从statusCheck.php中取出会话初始化,它就像一个魅力。我将把它保存在处理用户输入响应的其他人中,因为它确实有意义:用户点击由工作人员运行的“编译数据XY”按钮并需要一段时间。不耐烦,因为他已经点击了下一个按钮“显示此数据”...并且由于锁定的会话文件,我有一些整齐的队列用于这些操作。 :)

我仍然会将上述建议铭记在心,并确保改进我的代码。 :)