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

在GWT应用中使用原生JS发起异步请求的问题求助

GWT中调用异步JS函数(fetchToken)的解决方案

方法1:通过JSNI结合Java回调处理Promise链

GWT不支持async/await,但可以手动处理JS Promise的then/catch逻辑,通过Java回调接口接收异步结果:

  1. 定义Java回调接口
public interface TokenCallback {
    void onSuccess(String token);
    void onFailure(String error);
}
  1. 编写JSNI方法,完整处理fetch的Promise链
public native void fetchToken(String apiUrl, TokenCallback callback) /*-{
    $wnd.fetchToken(apiUrl)
        // 先解析response.json()的Promise
        .then(function(response) {
            return response.json();
        })
        .then(function(data) {
            // 调用Java回调的成功方法
            callback.@com.yourpackage.YourClass.TokenCallback::onSuccess(Ljava/lang/String;)(data.token);
        })
        .catch(function(error) {
            // 调用Java回调的失败方法
            callback.@com.yourpackage.YourClass.TokenCallback::onFailure(Ljava/lang/String;)(error.message || '请求失败');
        });
}-*/;
  1. 在Java代码中调用并处理结果
fetchToken("https://your-token-api.com", new TokenCallback() {
    @Override
    public void onSuccess(String token) {
        // 拿到token后的业务逻辑
    }

    @Override
    public void onFailure(String error) {
        // 错误处理逻辑
    }
});

方法2:改用XMLHttpRequest替代fetch(规避Promise处理)

如果fetch的Promise链处理麻烦,可以修改JS端的fetchToken函数,改用异步XMLHttpRequest实现,直接通过回调返回结果:

  1. 修改JS函数为XHR版本
function fetchToken(url, callback) {
    const xhr = new XMLHttpRequest();
    xhr.open('POST', url);
    xhr.setRequestHeader('Content-Type', 'application/json');
    xhr.responseType = 'json';
    
    xhr.onload = function() {
        if (xhr.status >= 200 && xhr.status < 300) {
            callback(null, xhr.response);
        } else {
            callback(new Error(`请求失败:${xhr.status}`), null);
        }
    };
    
    xhr.onerror = function() {
        callback(new Error('网络请求错误'), null);
    };
    
    xhr.send();
}
  1. 编写对应JSNI方法
public native void fetchToken(String apiUrl, TokenCallback callback) /*-{
    $wnd.fetchToken(apiUrl, function(error, data) {
        if (error) {
            callback.@com.yourpackage.YourClass.TokenCallback::onFailure(Ljava/lang/String;)(error.message);
        } else {
            callback.@com.yourpackage.YourClass.TokenCallback::onSuccess(Ljava/lang/String;)(data.token);
        }
    });
}-*/;

方法3:使用GWT 2.8+的JsInterop替代JSNI(更现代的方式)

JsInterop是GWT官方推荐的现代JS集成方案,能更优雅地处理JS Promise:

  1. 定义JS相关的JsInterop接口
import jsinterop.annotations.JsType;
import jsinterop.annotations.JsMethod;
import jsinterop.annotations.JsPackage;
import jsinterop.annotations.JsFunctionalInterface;

@JsType(isNative = true, namespace = JsPackage.GLOBAL)
public interface JsPromise<T> {
    void then(JsConsumer<T> onFulfilled);
    void then(JsConsumer<T> onFulfilled, JsConsumer<Throwable> onRejected);
}

@JsFunctionalInterface
public interface JsConsumer<T> {
    void accept(T value);
}

@JsType(isNative = true, namespace = JsPackage.GLOBAL)
public interface TokenResponse {
    String getToken();
}
  1. 声明JS函数的JsInterop方法
@JsMethod(namespace = JsPackage.GLOBAL)
public static native JsPromise<TokenResponse> fetchToken(String apiUrl);
  1. 在Java中调用并处理Promise
fetchToken("https://your-token-api.com").then(
    response -> {
        String token = response.getToken();
        // 处理token逻辑
        return null;
    },
    error -> {
        // 错误处理逻辑
        return null;
    }
);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 10:50:22