Skip to content

Modules make passing data back and forth much harder than functions #21

@domenic

Description

@domenic

When trying to offload work into another thread, IMO the syntactic overhead of importing/exporting is too high compared to other languages, or the blöcks proposal, or existing libraries.

Consider wanting to fetch a file at a computed-at-runtime URL, transform its contents, and return the result to the main thread. With this proposal, the best I can come up with is

const endpoint = ...;

const result = await worker([endpoint], module {
  const endpoint = await new Promise(resolve => {
    self.onmessage = ({ data }) => resolve(data[0]);
  });
  
  const res = await fetch(endpoint);
  const json = await res.json();

  export default json[2].firstName;
});

where worker() is a helper function somewhat similar to what is shown in https://github.com/tc39/proposal-js-module-blocks#use-with-workers , although I think it would have to spawn a Worker per invocation in order to allow reliable message passing and translation of default exports into return values. Which is itself not great.

This is worse than other languages, where you can do something equivalent to

const endpoint = ...;

const result = await worker(() => {
  const res = await fetch(endpoint); // closures in other languages can cross thread boundaries
  const json = await res.json();
  return json[2].firstName;
});

or the blöcks proposal, which requires explicit variable capture

const endpoint = ...;

const result = await worker{|
  const res = await fetch(${endpoint}); // special syntax to capture the variable from the outer scope
  const json = await res.json();
  return json[2].firstName;
|};

or something like greenlet which uses IIAFEs:

const endpoint = ...;

const result = await greenlet(endpoint => {
  const res = await fetch(endpoint);
  const json = await res.json();
  return json[2].firstName;
})(endpoint);

Is there a way to use this proposal to get something simpler? Otherwise I am worried that the benefits over libraries like greenlet are not enough to justify the extra overhead one has to incur.

Metadata

Metadata

Assignees

No one assigned

    Labels

    host environmentQuestions to be answered in each host environment

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions