Isomorphic Promise implementation?

60 views
Skip to first unread message

Alexander Bertram

unread,
May 20, 2025, 2:44:24 AMMay 20
to GWT Users
Hi all,

So long long ago, I wrote a Promise class for our GWT project to make easier to write complex async code that ran in the browser but could also be run in Junit tests running in the plain JRE, and sometimes on the server in cases where we could assume the Promise would complete synchronously. 

Fast forward 10+ years, and the Promise has long been standardized and baked into browsers themselves, WITH great support in DevTools for following the path of a Promise across resolutions.

I'm refactoring this class to use the browser's native Promise implementation. Normally the way I would do this is:
1. Align the Java implementation class to the Browser's Promise API
2. Add a supersource implementation that uses JSNI to invoke the browser's API when compiling.

BUT - is this still the "best" way to do this in 2025, with @JsTypes?
AND - there is already a Promise class in the elemental library that we use extensively, but it's a "native" class, so we can't use it in the JRE. Can I provide a JRE-safe implementation of elemental2.promise.Promise without monkey-patching elemental2-promise ?

Has anyone else implemented something similar?

Best,
Alex
 

Promise.java

Jens

unread,
May 20, 2025, 11:46:53 AMMay 20
to GWT Users
GWT itself uses an inner static class to define the native browser API via @JsType and then use that to implement the super source version. As an example you can look at Date at the very bottom: https://github.com/gwtproject/gwt/blob/main/user/super/com/google/gwt/emul/java/util/Date.java

I wouldn't write JSNI anymore. JSNI is hidden code in a comment which makes reference search etc annoying if the IDE does not have good JSNI support.

Using elemental2 Promise directly on the server isn't possible without replacing it with a JRE variant. A more natural approach would be using Java's CompletableFuture / CompletionStage and then emulating this API using Promises on the client. I can remember someone in this group did it that way and published the code on github somewhere. If you search the group you probably will find it to take a look.

-- J.

Colin Alworth

unread,
May 20, 2025, 1:05:29 PMMay 20
to GWT Users
The CF implementation for GWT was at https://github.com/OneGeek/GWT-CompletableFuture.

The Promise.java isn't going to be quite the same in Java and JS if you decide to go that way, but maybe it won't matter. Downstream then's and such are evaluated as microtasks after the current task/microtask completes, which keeps both keeps the stack from growing out of control and also lets other pending work complete before going back and picking up other work to resume. If you support threading when executing in a JVM (but not in the browser), you probably already have some other code to handle deferring work like this, and the required locks or other controls to keep your data safe from races - but those differences are usually meaningful, so I would hesitate to _generally_ conflate a browser Promise with JVM CompletableFuture with its assumptions about ForkJoinPool, etc.

Alexander Bertram

unread,
May 21, 2025, 4:09:01 AMMay 21
to GWT Users
Thanks both, for the pointers!
Reply all
Reply to author
Forward
0 new messages