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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 11:57:04