如何暂停Web工作者

时间:2016-10-21 16:46:29

标签: javascript multithreading cordova web-worker

我试图查看网络工作者文档,虽然我还没找到我要找的东西,但文档也不是很好,所以我想我只是问一下。

我正在使用Cordova与外部设备通信的移动应用程序。我需要每秒向外部设备发送一些命令。对于这些,我已经设置了Web Workers,它基本上就是线程的JS等价物。但是有一个命令要工作,必须转向外部设备。也就是说,如果设备在尝试处理它时获得任何其他命令,则命令将失败。为此,我只是想暂停我的主题。

在Java中这很容易,有一个public void thread.suspend()然后是thread.resume()。我的自然倾向是Web Workers将此作为默认函数。 Worker.suspend(),worker.resume(),但我找不到任何支持Workers有这个想法的文档,尽管对于多线程是一个非常普遍的期望。有没有这样固有的功能?如果没有,是否有实现类似功能的最佳实践?

1 个答案:

答案 0 :(得分:1)

此代码段显示如何

  1. 创建三个网络工作者
  2. 从网络工作者那里获取计数器值
  3. 暂停网络工作者
  4. 检测所有三名网络工作人员何时停止
  5. 重新启动网络工作者
  6. 由于StackOverflow片段的限制,Web工作者代码是内联的。

    function getInlineJS() {
        var js = $('[type="javascript/worker"]').text();
        var blob = new Blob([js], {"type": "text/plain"});
        return URL.createObjectURL(blob);
    }
    
    var worker_list = [];
    var worker_num = 3;
    var pause_count = null;
    
    function create_workers() {
        var index;
        for (index = 0; index < worker_num; index++) {
            var web_worker = new Worker(getInlineJS());
            var counter_selector = '#counter' + (index + 1);
            (function(selector) {
                web_worker.onmessage = function(event) {
                    var paused = event.data['paused'];
                    if (paused) {
                        pause_count++;
                    }
                    if (pause_count == worker_num) {
                        // At this point we know the workers have all stopped
                        $('#pause_count').text(pause_count);
                    }
                    var counter = event.data['counter'];
                    $(selector).text(counter);
                }
            })(counter_selector);
            worker_list.push(web_worker);
        }
    }
    
    /**
     * Send a bogus message to get the workers to send their counters
     */
    function update_counters() {
        var index;
        for (index = 0; index < worker_num; index++) {
            var message = {'index': index};
            worker_list[index].postMessage(message);
        }
    }
    
    /**
     * Send the pause flag to the workers
     * @param pause_state
     */
    function pause_counters(pause_state) {
        var index;
        for (index = 0; index < worker_num; index++) {
            var message = {'pause_flag': pause_state};
            worker_list[index].postMessage(message);
        }
    }
    
    var pause_state = false;
    $(document).ready(function() {
        create_workers();
        setInterval(update_counters, 1000);
        $('#pause').on('click', function() {
            pause_state = !pause_state;
            if (pause_state) {
                pause_count = 0;
            }
            else {
                $('#pause_count').text('');
            }
            pause_counters(pause_state);
            $('#pause').text(pause_state ? 'Start' : 'Stop');
        });
    });
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Web Worker</title>
    </head>
    <body>
        <div class="counter">
            Counter 1: <span id="counter1"></span>
        </div>
        <div class="counter">
            Counter 2: <span id="counter2"></span>
        </div>
        <div class="counter">
            Counter 3: <span id="counter3"></span>
        </div>
        <div class="button">
            <button id="pause" type="button">Stop</button>
        </div>
        <div>
            Pause Count: <span id="pause_count"></span>
        </div>
    </body>
    <script src="https://code.jquery.com/jquery-3.1.1.js"
            integrity="sha256-16cdPddA6VdVInumRGo6IbivbERE8p7CQR3HzTBuELA="
            crossorigin="anonymous"></script>
    <script src="sync.js"></script>
    <script type="javascript/worker">
    var pause_flag = false;
    var counter = 0;
    
    function run_command() {
        if (!pause_flag) {
            counter++;
        }
    }
    
    var interval = setInterval(run_command, 1000);
    
    onmessage = function(event) {
        if ('pause_flag' in event.data) {
            pause_flag = event.data['pause_flag'];
        }
        var message = {
            "paused": pause_flag,
            "counter": counter
        };
        postMessage(message);
    };
    </script>
    </html>