alesgenova / post-me

📩 Use web Workers and other Windows through a simple Promise API
https://www.npmjs.com/package/post-me
MIT License
492 stars 13 forks source link

Add support for functions #38

Closed yovanoc closed 3 years ago

yovanoc commented 3 years ago

I need to encrypt file in a worker, and get back a progress, my function take a progress callback, and of course this callback can't be cloned. But I know that this is possible to transfer into workers and it will help me a lot to have this feature in post-me

alesgenova commented 3 years ago

You're right transferring call parameters and results is something I want to implement soon to improve performance in some cases. However even with that in place I'm not sure you'd be able to take advantage of it to report progress. That's because I don't think you can transfer functions, and even if you could, then you would not have them available in the parent window to get the progress.

That said, I think you can still get the progress using the current version of post-me with this workarount. It's not pretty but I think it can work :)

Parent code

//...
ParentHandshake(messenger).then(connection => {
  const remoteHandle = connection.remoteHandle();

  const currentTaskId = "some-unique-id";
  remoteHandle.call("encrypt", [], currentTaskId).then(result => {
    //...
  });

  // Listen for the progress of the task you just dispatched
  remoteHandle.addEventListener("progress", (payload) => {
    const { taskId, progress } = payload;
    if (taskId === currentTaskId) {
      console.log(progress);
    }
  })
});

Worker code

let localHandle;

const methods = {
  encrypt: (data, taskId) => {
     if (localHandle) {
        localHandle.emit("progress", {taskId, progress: 0});
        localHandle.emit("progress", {taskId, progress: 25});
        localHandle.emit("progress", {taskId, progress: 50});
        localHandle.emit("progress", {taskId, progress: 75});
     }
  },
}

// ...

ChildHandshake(messenger, methods).then(connection => {
  localHandle = connection.localHandle();
})

Let me know if it works, maybe I can implement something similar at the library level and expose a nicer interface to the user.

yovanoc commented 3 years ago

Yes thanks you its working. A nicer interface for this will be perfect! thanks

alesgenova commented 3 years ago

@yovanoc I have implemented a more convenient way of reporting progress/partial results back to the caller. See PR #39

yovanoc commented 3 years ago

Nice! Better like this

alesgenova commented 3 years ago

I actually changed my mind, and decided that it would be more elegant elegant to generalize support for callbacks. As soon as I merge the PR above, you'll be able to pass one or more callbacks just like any other parameter using the regular call method:

const onProgress = (progress) => {
  console.log(progress);
}

remoteHandle.call("slowSum", 2, 3, onProgress).then(result => {
    //...
  });
alesgenova commented 3 years ago

The feature is available in version 0.3.2 on npm

yovanoc commented 3 years ago

Nice! gg

alesgenova commented 3 years ago

Added support for transfer too: