flutter 如何将 Stream 转 Future

1,516 阅读1分钟

有时候会写一个异步方法,可以直接返回 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 方法。

特意记在这里,以免忘记。