Obtain data synchronously from WebWorker?

不问归期 提交于 2019-12-04 05:50:46
JF Bastien

Edit: Note that SharedArrayBuffer was disabled by default in all major browsers (on January 5th 2018) in response to Spectre.


JavaScript's SharedArrayBuffer sounds like a perfect fit for you:

  • new technologies: just moved to Stage 4 at January's TC39 meeting (in time for ES2017)
  • won't reliably run on older browsers (older versions have a different API, or no implementation available)
  • esoteric hack (similar to the C++ memory model)
  • works

For your purpose, you want to have the WebWorker wait until data is available. With SharedArrayBuffer you can use a spinloop (Atomics.load until the value changes) but it would be better to use Atomics.wait until the other worker sends you an Atomics.wake. This later API is heavily inspired by Linux's futex and won't needlessly spin if the value you're waiting on isn't available.

// Main program:
var w = new Worker("worker.js")
var sab = new SharedArrayBuffer(1024);
w.postMessage(sab);
var i = new Int32Array(sab);
// Maybe wait for worker.js to message back that it's ready through onmessage?
//
// Fill i with some data!
// ...
//
// Notify one worker, at location 0, with value 1.
Atomics.store(i, 0, 1);
Atomics.wake(i, 0, /* notify count */ 1);


// worker.js:
var sab;
var i;
onmessage = function (ev) {
    sab = ev.data;
    var i = new Int32Array(sab);
}
// Maybe tell the main program we're ready through postMessage?
//
// ...
// Wait until location 0 isn't value 0
Atomics.wait(i, 0, 0);

Remember: it's a bad idea to block the main thread! Your site will be unresponsive if you do that. Your question was asking about blocking a worker, but readers may be interested in waiting from the main thread. Don't!

A very similar, and compatible, API will eventually be available in WebAssembly. Here's an early draft proposal. When I say compatible: we expect that WebAssembly will be able to use the same SharedArrayBuffer as JavaScript does, and both will be able to communicate through it seamlessly.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!