Skip to content
padolsey edited this page Oct 7, 2014 · 3 revisions

In 0.4.0 Operative introduces a Transfers API. This will degrade to either structured-cloning or JSON strings in various older browsers, but for newer browsers (Chrome 17+, Firefox 18+, Opera 15+, Safari 6+) it will use a feature of postMessage() which allows you to transfer ownership of objects to/from the worker, instead of having to clone or serialize. You must use a Transferable object for this to work, such as an ArrayBuffer.

Here's an example of transferring 4MB without using the Transfers API:

var dataReceiver = operative(function(data, cb) {
  cb('You just gave me ' + data.length + ' bytes-worth of data');
});

dataReceiver(new Uint8Array(1024*1024*4), function(message) {
  alert(message);
});

And with the transfers API:

var dataReceiver = operative(function(buffer, cb) {
  data = new Uint8Array(buffer);
  cb('You just gave me ' + data.length + ' bytes-worth of data');
});

var arr = new Uint8Array(1024*1024*4);

dataReceiver.transfer(
  arr.buffer,   // The data you want to pass to the worker
  [arr.buffer], // An array of Transferable objects (that exist
                // somewhere within the data structure above) that
                // you wish to transfer to the worker
  function() {  // regular callback
    done();
  }
);

The data you pass to the worker can still be any type you desire, but, if within that, there is an object you wish to transfer then you'll want to pass that in the transfers array, e.g.

someOperative.transfer(
  {
    name: 'some arbitrary object',
    someData: [1, 2, 3, aBufferIWantToTransfer]
  },
  [aBufferIWantToTransfer]
);

Transferring from the worker:

Callback pattern:

(If you've defined a callback in your operative-calling code):

var o = operative(function(a, b, c, callback) {
  callback.transfer(someResultBuffer, [someResultBuffer]);
});

o(function(theResultBuffer) {
  theResultBuffer; // The result
});

Promise pattern:

(If you're using a promise/thenable in your operative-calling code):

var o = operative(function(a, b, c) {
  var deferred = this.deferred();
  deferred.transferResolve(someResultBuffer, [someResultBuffer]);
  // Or reject via transferReject()
});

o.then(function(theResultBuffer) {
  theResultBuffer; // The result
}, function(failure) {
  // ...
});
Clone this wiki locally