有时候会写一个异步方法,可以直接返回 Future 对象。但是当我们接入第三方插件时情况却有所变化,他们会要求传一个监听函数进去。或者订阅 Stream。这样的话,异步方法就没法返回结果了。但是我们可以把 Stream 流转换成 Future 返回回去。
Future<bool> wxPay() async {
var streamController = StreamController<bool>();
// 异步操作
asyncOp(callbak: (isSuccess){
streamController.add(isSuccess);
streamController.close();
});
return await streamController.stream.last;
}
这是一个简单的示例,最后返回的是 stream 中的最后一个 item 。streamController.stream.last 的类型就是 Future。在异步回调函数中,只需要把结果 add 到 stream 中就可以了, add 后一定要调用 streamController.close() 方法,不然哪来的 .last 呢?只有关闭了,才存在最后一个 item 。
Completer
2021年5月5日编辑
经过一段时间的学习,在别人代码里看到了 Completer 这个类。通过它可以更方便的实现类似 js 的 new Promise((resolve,reject)=>{resolve('hello world')}) 效果。
还是以上面最开始的微信支付为例
Future<bool> wxPay() {
Completer<bool> c = Completer();
// 监听支付结果
wx.listen((bool success){
c.complete(success);
});
wx.pay();
return c.future;
}
可以看到这样的写法更一目了然。但是要注意只能调用一次 complete 方法。
特意记在这里,以免忘记。