Correct way to transfer TypedArrays?

Viewed 1888

Given a typed array like Uint8Array it seems there are two approaches to transfer them via a worker.

Option 1

Send the buffer directly and cast it on the receiving side:

Sender: postMessage({fooBuffer: foo.buffer}, [foo.buffer])

Receiver: const bar = new Uint8Array(msg.data.fooBuffer)

Option 2

Send the TypedArray and only transfer its buffer:

Sender: postMessage({foo: foo}, [foo.buffer])

Receiver: use foo as-is.


It seems to me that option 2 is preferable since the receiver doesn't need to know about the type of data, and its less code - but I keep coming across examples only in the style of option 1.

More to the point, in my current code, only option 2 works. I've confirmed that the data is transferred since only after sending, foo[0] becomes undefined.

Is using option 2 okay, even though it's not the norm for sample code I'm seeing?

1 Answers

The difference is totally insignificant. If you pass the typed array, all you really pass is information about what type it was. One way or another, new instance of the array view will be created using the moved buffer.

So it's really up to your needs. Either way works, check this fiddle.

index.js

var worker = new Worker(url);

worker.addEventListener("error", function(e) {
    console.warn("Worker error:", e);
});
worker.addEventListener("messageerror", function(e) {
    console.warn("Message error:", e);
});

var arrayBuffer = new Float64Array([1,2,3,4,5]).buffer;
var array = new Float64Array([1,2,3,4,5])
worker.postMessage({name:"buffer", data:arrayBuffer}, [arrayBuffer]);
worker.postMessage({name:"array", data:array}, [array.buffer]);

worker.js

  self.onmessage = function(e) {
    switch(e.data.name) {
      case "buffer" : 
          console.log("Array buffer:", new Float64Array(e.data.data))
      break;
      case "array": 
          console.log("Array:", e.data.data);
          break;
      default:
        console.error("Unknown message:", e.data.name);
    }
  }
Related