如何暂停Web Workers

3
我已尝试查阅Web Worker文档,虽然没有找到我需要的内容,但文档也不是很好,所以我想直接询问。
我正在使用Cordova开发一个与外部设备通信的移动应用程序。有一些命令需要每秒发送到外部设备。为此,我已经设置了Web Workers,这基本上相当于JavaScript中的线程。但是有一条命令需要占用外部设备才能运行。也就是说,在处理该命令时,如果设备收到任何其他命令,该命令将失败。为此,我只想暂停我的线程。
在Java中,这很容易。有一个public void thread.suspend(),稍后是thread.resume()。我的自然倾向是Web Workers会有这个默认函数。Worker.suspend(),worker.resume(),但我找不到支持这一想法的任何文档,尽管这是多线程的一个普遍期望。是否有这样的内在功能?如果没有,是否有实现类似功能的最佳实践?

设备的接口是什么?您能修改接口吗? - user3657941
这是通过WAP的TCP/IP。我认为修改它比在命令期间停止发送消息要繁琐得多。 - EvSunWoodard
你能给每个工作进程发送一条消息,要求它暂停吗?然后每个工作进程可以发送一条消息,表示它已经暂停。当你收到所有的消息后,就可以运行长命令了。 - user3657941
是的,我想这可以运行。我很困惑为什么它不是内置的。 - EvSunWoodard
1个回答

2
这段代码展示了如何:
  1. 创建三个Web Worker
  2. 从Web Worker获取计数器的值
  3. 暂停Web Worker
  4. 检测所有三个Web Worker何时停止
  5. 重新启动Web Worker
由于StackOverflow代码片段的限制,Web Worker代码是内联的。

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>


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接