You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在GWT中将Java回调传递给返回Promise的JSNI方法?

Handling Promises from JSNI in GWT 2.7 (No JsInterop)

Hey there! Since you're stuck with GWT 2.7 and can't leverage JsInterop, I totally get how tricky it is to handle Promises returned from JSNI methods called from Java. I’ve dealt with this exact scenario before, so let’s break down a practical approach that works:

1. First, Define a Java Callback Interface

GWT 2.7’s Java code can’t natively understand Promise objects, so we need a way to bridge the Promise’s then/catch callbacks to Java. Start by creating a simple callback interface that your JSNI code can invoke:

public interface PromiseCallback<T> {
  void onSuccess(T result);
  void onFailure(Throwable error);
}

This interface will let us pass success/failure logic from Java into the JSNI layer.

2. Wrap the Promise in JSNI

Next, write a JSNI method that calls your JavaScript function (the one returning a Promise), then hooks up the Promise’s handlers to trigger your Java callback. Here’s an example:

public native void callJsPromiseMethod(PromiseCallback<String> callback) /*-{
  // Replace this with your actual JS function that returns a Promise
  const jsPromise = $wnd.yourJsFunctionThatReturnsPromise();

  jsPromise.then(function(successResult) {
    // Invoke the Java callback's onSuccess method
    callback.@com.yourpackage.YourClass.PromiseCallback::onSuccess(Ljava/lang/String;)(successResult);
  }).catch(function(error) {
    // Convert JS error to a Java Throwable for error handling
    const javaError = @java.lang.RuntimeException::new(Ljava/lang/String;)(error.message || error.toString());
    callback.@com.yourpackage.YourClass.PromiseCallback::onFailure(Ljava/lang/Throwable;)(javaError);
  });
}-*/;

Make sure to replace com.yourpackage.YourClass with your actual package and class name, and $wnd.yourJsFunctionThatReturnsPromise() with the correct reference to your JavaScript method.

3. Handle Complex Return Types (If Needed)

If your Promise returns a complex JavaScript object instead of a primitive/string, you’ll need to map it to a Java class. First create a simple Java class to hold the data:

public class JsUserData {
  private String username;
  private int userAge;

  // Empty constructor required for JSNI to instantiate
  public JsUserData() {}

  // Getters and setters
  public String getUsername() { return username; }
  public void setUsername(String username) { this.username = username; }
  public int getUserAge() { return userAge; }
  public void setUserAge(int userAge) { this.userAge = userAge; }
}

Then update your JSNI method to convert the JS object to this Java class:

public native void fetchUserData(PromiseCallback<JsUserData> callback) /*-{
  $wnd.fetchUserPromise().then(function(jsUser) {
    // Create a new instance of your Java data class
    const javaUser = @com.yourpackage.JsUserData::new()();
    // Map JS object properties to Java fields
    javaUser.@com.yourpackage.JsUserData::setUsername(Ljava/lang/String;)(jsUser.username);
    javaUser.@com.yourpackage.JsUserData::setUserAge(I)(jsUser.age);
    // Pass the Java object to the success callback
    callback.@com.yourpackage.PromiseCallback::onSuccess(Ljava/lang/Object;)(javaUser);
  }).catch(function(error) {
    const javaError = @java.lang.RuntimeException::new(Ljava/lang/String;)(error.message);
    callback.@com.yourpackage.PromiseCallback::onFailure(Ljava/lang/Throwable;)(javaError);
  });
}-*/;

4. Use the Callback in Java

Now you can call your JSNI method from Java and handle the Promise results with your callback:

callJsPromiseMethod(new PromiseCallback<String>() {
  @Override
  public void onSuccess(String result) {
    // Handle successful Promise resolution
    GWT.log("Promise resolved! Result: " + result);
  }

  @Override
  public void onFailure(Throwable error) {
    // Handle Promise rejection
    GWT.log("Promise rejected with error: " + error.getMessage(), error);
  }
});

Key Notes to Remember

  • Reference JS Functions Correctly: Ensure your JavaScript method is accessible via $wnd (the global window object) in JSNI, otherwise GWT won’t find it.
  • Async Context: Remember that Promise callbacks run asynchronously in GWT’s event loop—don’t expect immediate results, and avoid blocking the main thread.
  • Type Conversion: When passing data between JS and Java, make sure to match types correctly (e.g., JS number maps to Java int/double, JS boolean to Java boolean).
  • Error Handling: Always wrap JS errors in a Java Throwable so you can properly log and handle them in your Java code.

内容的提问来源于stack exchange,提问作者DevOne

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 08:53:05