- 当你想执行一个异步函数,并想让他返回结果的时候,你会用到
Future<类型> 函数名() { /// 代码块}
,但是你如果不想让他立刻返回,而是等你的命令再返回应该怎么办?
- 这时候就可以用到Completer。场景是这样的,我通过Modbus协议,执行一个异步函数,发送一段指令,代码是这样的
Uint8List data = Uint8List(2);
ByteData.view(data.buffer)..setUint8(0, 3);
var data = await sendData(data);
Future<Uint8List> sendData(Uint8List data)
{
_connector.write(function, data);
}
这时候指令通过_connector.write(data);
方法已经发过去了,但是
Future<Uint8List> sendData(Uint8List data)
这个方法还没有返回值,而且我这里也不知道要返回什么,我是否可以先把这个异步方法挂着,先返回一个future,但是这个future 是没有完成的,等到Modbus 协议的服务端给我返回消息时,我再让他完成。
- 这时候定义一个Completer,返回他的future
Completer _completer;
Future<Uint8List> sendData(Uint8List data)
{
_completer = Completer<Uint8List>();
_connector.write(function, data);
return _completer.future;
}
这里就算返回了 _completer.future;
前面的var data = await sendData(data);
也不会执行完,而是在这里挂着,什么时候异步执行完了,这句才会执行完毕。
- 剩下的就简单了,等监听到服务端的返回的消息时,把消息处理处理,然后执行
/// responseData 是经过处理的服务端返回的消息,也就是你想到的数据
_completer.complete(responseData);
这句代码执行后,Future<Uint8List> sendData(Uint8List data)
这个异步函数才算执行完成,相应的var data = await sendData(data);
里的data 才会获取数据。