Dart中如何等待JsObject?Flutter Web SignalR调用报错处理
解决Flutter Web中使用SignalR JS库的invoke错误及Promise等待问题
错误原因分析
你遇到的「TypeError: Instance of 'JsObject': type 'JsObject' is not a subtype of type 'JavaScriptFunction'」本质是Dart与JS互操作时的类型不匹配:直接将HubConnection对象的invoke属性当作Dart函数调用,而非通过JS互操作机制调用JS方法;同时未正确将JS Promise转换为Dart Future,导致无法等待服务器返回结果。
具体解决步骤
1. 添加依赖并配置JS绑定
首先在pubspec.yaml中添加js包依赖:
dependencies: js: ^0.6.7
创建signalr.dart文件,用@JS注解强绑定SignalR的核心API,避免直接操作无类型的JsObject:
import 'package:js/js.dart'; @JS() library signalr; // 绑定HubConnectionBuilder构造函数 @JS("HubConnectionBuilder") external HubConnectionBuilder hubConnectionBuilder(); @JS() class HubConnectionBuilder { external HubConnectionBuilder withUrl(String url); external HubConnection build(); } // 绑定HubConnection核心方法 @JS() class HubConnection { external JsPromise<void> start(); // 支持多参数调用,可根据实际需求调整参数个数 external JsPromise<dynamic> invoke(String methodName, [dynamic arg1, dynamic arg2]); } // 绑定JS Promise @JS() class JsPromise<T> { external JsPromise<T> then(Function(T result) onFulfilled); external JsPromise<T> catchError(Function(dynamic error) onRejected); }
2. 正确调用SignalR方法并处理Promise
使用dart:js_util的promiseToFuture方法,将JS Promise转换为Dart Future,实现异步等待;同时严格通过绑定的API调用方法,避免类型错误:
import 'dart:js_util' as js_util; import 'signalr.dart'; Future<void> initSignalR() async { try { // 构建连接 final connection = hubConnectionBuilder() .withUrl('https://你的SignalR服务器地址/Hub路径') .build(); // 启动连接,等待完成 await js_util.promiseToFuture(connection.start()); print('SignalR连接已建立'); // 调用服务器方法,等待返回结果 // 示例:传递两个参数,根据实际方法调整 final result = await js_util.promiseToFuture( connection.invoke('你的服务器方法名', '参数1', 2) ); print('服务器返回结果:$result'); } catch (e) { print('SignalR操作出错:$e'); } }
3. 复杂参数处理
如果需要传递对象、数组等复杂参数,需用js_util.jsify将Dart类型转换为JS兼容类型:
// 转换Dart Map为JS对象 final jsParams = js_util.jsify({ 'username': 'test', 'age': 25 }); final result = await js_util.promiseToFuture( connection.invoke('复杂参数方法', jsParams) );
关键注意事项
- 确保Flutter Web的
index.html中已正确引入SignalR JS库:<script src="https://cdnjs.cloudflare.com/ajax/libs/microsoft-signalr/7.0.10/signalr.min.js"></script> - 避免直接通过
js.context获取HubConnection或调用方法,强类型绑定能大幅减少类型错误 - 所有JS异步操作必须通过
promiseToFuture转换为Dart Future,才能用await等待结果
内容的提问来源于stack exchange,提问作者Coder3000
相关产品推荐
相关产品推荐

