Javascript 两个JS webworkers同时运行:一个被卡住

Javascript 两个JS webworkers同时运行:一个被卡住,javascript,php,ajax,multithreading,web-worker,Javascript,Php,Ajax,Multithreading,Web Worker,我正在开发一个封闭系统的web应用程序,帮助公司处理日常的在线商务事务。这意味着一方面它不会向公众开放,另一方面:它必须处理大量数据,同时保持流畅的工作体验 这就是为什么我求助于JS中的web工作者在后台运行各种数据库访问和数据加载。 我的理解是,不仅主UI/mainjs保持不间断,而且不同的web工作者在运行时也不会相互妨碍 我现在有以下设置: mainJS:在pageload上运行的函数statusCheck: function statusCheck() { if(typeof(w

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

这就是为什么我求助于JS中的web工作者在后台运行各种数据库访问和数据加载。 我的理解是,不仅主UI/mainjs保持不间断,而且不同的web工作者在运行时也不会相互妨碍

我现在有以下设置:

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是一个worker,它的运行方式如下:

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对象,该对象提供系统状态

这个很好用

现在我有了另一个worker,它应该通过点击链接来启动,从而有效地调用一些php来执行操作: mainJS装载工

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));
            }
        }
}
每次单击某个链接,就会调用它,创建一个唯一命名的worker,运行它,接收数据,并通知worker关闭

php再次完成它的工作,并在冗长过程的每一步之后在DB中写入进度更新。我通过上述重复状态检查从数据库获取这些进度更新

现在,我可以在数据库中看到带有时间戳的条目,因此我知道它们在各自的时间被写入。 因此,这两名员工都能完成工作并可靠地运行。但我注意到,每当我启动手动随机命名的worker时,statusCheck实际上停止执行。它只是被卡住了。。。我能够通过两个工人的控制台输出来确认这一点。因此,似乎卡住的不是主JS,而是状态检查实际上暂停了。。。并在loadWorker完成后继续

我是不是错过了一些基本的东西?由于我对网络工作者这个概念还不熟悉,任何见解都将不胜感激


Thanx:

你的问题缺乏资源来真正找出到底出了什么问题。我可以同意这一点,即使是同步操作。我对循环和同步XHR请求都进行了测试

不过,我有很多建议

首先,除非您使用CPU密集型算法处理数据,否则web工作者是在浪费时间。除非您明确要求XHR请求阻止主线程,否则XHR请求不会阻止主线程

在statusCheck中,您声明var w_uustatusCheck,这意味着一个局部变量。因此,从外部范围看,它总是空的。一旦辅助进程中没有代码运行,它可能会被垃圾收集。 不要使用XMLHttpRequest.onreadystatechange。使用onload和onerror。 变量的随机唯一ID几乎总是错误的。如果您需要存储worker reference,可以给它一个合理的名称,例如它应该加载的url,或者使用增量id。 不要对发布到web worker的数据进行字符串化。它已经由浏览器为您完成,可能是以更优化的方式。将数据转换成某种东西是人们对网络工作者最常见的愚蠢行为。
此外,在发布问题时,至少要确保代码有一定的意义。在您的帖子中,花括号不匹配。

好的。。我想出来了: 我找错地方了。事实证明,我已经在工作人员调用的所有php脚本中初始化了我的php会话。我的两个平行工人都叫一个。因此,会话文件被第一个php脚本锁定,第二个脚本必须等待它再次打开。不是工人或JS受到阻碍,而是php

现在,我从statusCheck.php中取出会话初始化,它就像一个符咒。我将把它保存在处理用户输入响应的其他程序中,因为在那里它实际上是有意义的:用户单击按钮compiledataxy,这是由工作人员运行的,需要一段时间。虽然他很不耐烦,但他已经点击了“下一步”按钮显示此数据。。。由于会话文件被锁定,我对这些操作有一个整洁的队列:


我仍将牢记上述建议,并确保改进我的代码:

首先:谢谢你的指点!我会调查他们,尝试他们,看看结果如何。至于是否使用网络工作者。。。该应用程序的第一个版本已经使用了几年,在最初的想法之后,越来越多的功能开始发挥作用。到目前为止,我们正在进行繁重而冗长的计算。至于缺少的大括号:我复制了工作代码,并在编辑器中删除了不相关的部分。。我想我有一个太多了。。可以我会尝试一切,并张贴结果在这里。祝你周末愉快!!本想询问随机ID。。有没有一个合乎逻辑的原因,为什么他们几乎总是这样
怎么了?我的目标是让它们都独一无二,这样就不会有任何干扰。由于它们在执行后立即关闭,并且不需要在任何其他上下文中被知道。。。我认为var名称不能有特殊字符?!所以我创建了这样的名称:WorkerID_uu+random_unumber+now@AurelEngleEngelmann从什么时候开始,随机数每次都意味着不同的数?我认为使用随机数代替增量(例如0、1、2、3)是不合理的,因为它提供了有关创建顺序的信息,所以也更容易调试。创建随机数的方式看起来像是你认为网格中的随机数越多越好,但事实并非如此。是的,变量名不能有特殊字符。但是对象属性可以。这是有效的:var dd={☺:笑脸}这也是:窗户[☺] = smileyI不知道特殊字符。:…我知道Math.random不会一直可靠地产生不同的结果..但由于此函数由用户单击鼠标运行,因此我将随机数与now时间戳组合在一起。这样,我认为我将始终具有不同的值-即使在Math.random确实给出相同的数字,或者即使操作系统在同一个实例中触发了双击..这是我不久前因为鼠标出现故障而遇到的情况。无论如何..感谢您的洞察力,我将在周一尝试并发布结果:是这样吗?如何?我只看到JS和文档消息。没有php输出。而且,任何地方都没有错误。只是延迟。也许我没有你那么开明,所以也许你可以在这里帮助我…如果你查看控制台,你会看到其中一个请求正在加载,没有收到任何数据。这会给你足够的提示,让你知道问题出在与服务器的通信中,你可以轻松地检查它是否与web workers无关。Y你仍然需要弄清楚问题是什么,但至少你不会发布一个没有水晶球就无法回答的问题。还要注意的是,说“也许我不如你开明”经常被用作粗鲁的讽刺,所以最好避免在互联网上出现,以避免激烈的辩论。你是对的。这就是我的理解终于出来了。我问问题的时候脑子里确实有我的控制台。日志。事实上,我提到他们证实了我的问题。我不明白的是,我的答案怎么没有解决原来的问题,并获得了否决票。控制台没有告诉我确切的问题,而是它的影响。这需要解释。而且没有足够的经验在这些问题上,我在这里求助于提问。事实上,我自己提出了一个解决方案,这应该是投票的理由——如果有的话。不过:感谢您的努力和宝贵的提示,让我的代码变得更好。