-
Notifications
You must be signed in to change notification settings - Fork 383
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support for "asynchronous exports" #4916
Comments
Ah, I was wondering when someone would request that. 😅 It's kind of challenge to support, actually. I've been thinking about it on and off but did not find a good solution yet. Do you have a use case at the moment? Or is it hypothetical for you at this point? |
FWIW, we also do not have support for async module initializers (which IMO likely have more use-cases). |
Yes, I think this is what I want? What is the difference exactly? The use case I had in mind falls under the "resource initialization" category described in the original proposal. Most serverless frameworks expect you to export some kind of "handler" function and (at least in our Typelevel.js ecosystem) creating that function typically requires us to do async things e.g. connecting to some servers/databases. Our current workaround is to hide this async initialization in the handler function itself, which is also async, but this is less than ideal. |
The difference could be summarized like this: // asynchronous export:
export let Foo = await makeFoo();
// asynchronous module initialization
await performSideEffectsAsync(); In Scala.js what we call "module initialization" is closer to the user-level concept of "main method". Since we create potentially multiple modules, we can have several "main methods" that are in those separate modules, so they act more like module initializers. In your case I think you have the "asynchronous export" use case. Note that in JavaScript these two things are the same. They're both relying on top-level |
Here is a summary of my least bad idea so far. Asynchronous exportMy best idea would be to introduce a new annotation object Container { // not necessary in Scala 3
@JSExportTopLevelAsync("foo")
val foo: js.Promise[Int] = ...
} This would emit something equivalent to export const foo = await Container.foo; Asynchronous module initializerThis is really "least bad" more than "best", but here is what I have. Add a new kind of def mainMethod(): Any where the result is expected to be a JavaScript thenable (a await mainMethod(); Why |
For both of the solutions, have you considered a parameter |
I had not considered that. I don't think that's better, though. Boolean flags are usually a code smell, compared to a dedicated name.
Yes, I had the same idea at some point and rejected it for the same reasons. |
Interesting :) I've not heard that perspective. The way I looked at this is in terms of available combinations: If there are multiple independent options, it's better to express them as boolean flags to avoid combinatorial explosion of names. For exports there are currently no other options (and its unclear to me whether there will). For module initializers, we can construe the presence of args to be such an option (but indeed we're following the naming pattern there). |
As far as I know there is currently no way to express an export of a value that is computed asynchronously. In
ES6ES2017ES2022 (sorry, didn't realize how recent it is :) this can be accomplished via a top-levelawait
.The text was updated successfully, but these errors were encountered: