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

Flutter Web中如何从异步JS函数获取回调或返回值至Dart

在Flutter Web中实现JS异步结果返回Dart的解决方案

针对你遇到的JS异步函数结果无法返回至Dart的问题,以下是具体的原因分析和可行方案:

错误原因分析

  1. 示例1:仅调用JS函数但未处理其返回的Promise,因此无法获取结果。
  2. 示例2:js.context.callMethod返回的是JsObject而非原生JS Promise,promiseToFuture无法识别这种对象的then方法,导致报错。
  3. 示例3:未正确声明JS异步函数的返回类型,Dart无法将返回的JS Promise转换为可await的Future,引发类型错误。

可行实现方案

步骤1:确保JS函数全局可访问

你的JS代码无需大幅修改,只需确保fileOpen函数挂载到全局window对象上(通常在index.html的<script>标签中定义即可):

let fileHandle;

async function fileOpen() {
    try {
        [fileHandle] = await window.showOpenFilePicker();
        const file = await fileHandle.getFile();
        
        if (file) {
            const parser = new window.AppInfoParser(file);
            const result = await parser.parse();
            return result;
        } else {
            return 'File not selected';
        }
    } catch (err) {
        // 捕获用户取消文件选择等异常
        throw err;
    }
}

步骤2:Dart端正确处理JS Promise

使用package:js和js_util库,正确声明JS异步函数并将其Promise转换为Dart Future:

import 'package:js/js.dart';
import 'package:js/js_util.dart';

// 定义JS Promise的Dart映射类,让Dart识别Promise接口
@JS()
class Promise<T> {
  external Promise then(void Function(T result) onSuccess, [Function onError]);
}

// 声明全局的JS异步函数,返回Promise
@JS()
external Promise<dynamic> fileOpen();

// 在点击事件或异步方法中调用并获取结果
Future<void> handleFileOpen() async {
  try {
    dynamic result = await promiseToFuture(fileOpen());
    // 处理返回的结果,比如打印或更新UI
    print('Received result from JS: $result');
    if (result is Map) {
      print('App icon base64: ${result['icon']}');
    }
  } catch (e) {
    // 处理异常,比如用户取消文件选择
    print('Error occurred: $e');
  }
}

关键注意点

  • 必须用try-catch包裹异步调用,因为用户取消文件选择器时window.showOpenFilePicker会抛出异常,需要在Dart中捕获。
  • 通过@JS()注解声明的函数必须与全局JS函数名完全一致,确保Dart能正确找到对应的JS函数。
  • 使用promiseToFuture将JS Promise转换为Dart Future,才能用await获取结果。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 10:10:28