pub / sub是拍打的好模式吗

时间:2018-07-19 19:37:25

标签: dart flutter

我才刚刚开始学习颤振。目前,我仍在与期货作斗争。

因此,我计划编写一个发布/订阅模式类,该类应该是异步结果的中央消息代理。

假设某些方法需要http通信的答复。

它将使用我的_callbackMethodCall订阅HTTP_AUTHORIZE_USER操作的结果,如下所示:

broker.subscribe( HTTP_AUTHORIZE_USER, _callbackMethodCall );
sharedHttpHelper.execute();

另一处,http类将这样发布其结果,其中调用者已将HTTP_AUTHORIZE_USER传递为mySubscriberChannel:

broker.publish( mySubscriberChannel, actualResult );

我知道我可以使用

someFutureObject.then( <doSomething> );

实际上,我认为pub / sub可以更好地分离异步交互的双方。当将结果发回给不同的订户时,它更加灵活。

您能解释一下,为什么someFutureObject.then()及其周围的自定义代码比发布/订阅更好吗?

并可能提供一些示例代码,以更好的/标准的方式使用futures / then()替换pub / sub代码吗?

还是我最终可以将异步模式替换为另一个异步模式,并且这样做可能不会赢得任何好处?

2 个答案:

答案 0 :(得分:2)

我想从您的问题中,您要问两件事:

  1. 您应该使用Future / Async还是回调
  2. 您应该有一个执行异步计算的中央类还是要在每个小部件的基础上执行异步计算

要提出具体建议,我想我需要更多信息。但是,我可以给您一些一般性建议。

1:将来或回调

在这种情况下,我强烈建议您花点时间学习Dart中的期货和异步方法。您最终会遇到需要使用它们的东西,因此您现在最好弄清楚它。如果您真的不知道该怎么做,我建议您制作一个罐头示例,然后将其发布到SO上,或在一个飞镖/飞镖通道中询问。

话虽如此,但概述如下:

在dart中,Future类似于Java中的Promises(我看到您至少对JS有一定的经验)。他们执行异步计算,然后在完成后调用您传递给then的任何回调。

但是,在dart中也有asyncawait关键字。如果标记方法async,则其签名必须指定Future的返回值。在函数内,如果有任何调用的方法将返回Future,则可以使用future.then(callback...)来代替await future。我相信JS的最新迭代之一与此类似。

根据您的问题: someFutureObject.then( <doSomething> );将成为var result = await someFutureObject; <dosomething>;

如果您在flutter网站上浏览,则对此有更深入的解释。

2:中央vs每个窗口小部件

这在很大程度上取决于您的具体情况。我会做的是将您的asynchronous交互归类为a)每次运行该应用一次,b)对全局状态有影响或c)对于该应用的特定部分而言是本地的。

对于每次运行只发生一次的事情,您可能只需在加载屏幕上执行一次(或在启动仍处于启动状态时)就可以摆脱这种情况-例如,例如从远程服务器加载常规设置。 / p>

对于会影响全局状态(即登录和注销)的事物,我建议使用InheritedWidgets和相应的StatefulWidget。这样,您可以简单地在较低级别使用继承的窗口小部件并使用各种相关属性,并确保如果属性更改,窗口小部件将重新生成。

对于应用程序特定部分的本地内容,我建议使用FutureBuilder,因为它有助于诸如在加载时显示不同的小部件之类的东西。

就执行实际http调用或其他任何操作的逻辑而言,最好是针对所使用的各种API创建类。如果出于某种原因需要跟踪特定于http调用的内容,则可以使用Singleton或Registry模式使API调用类能够保持状态。

除非有特殊原因,否则实际上不需要发布/订阅系统。尽管如果绝对觉得需要使用它,请查看eventbus plugin ...

答案 1 :(得分:1)

如果仅等待单个结果(例如单个HTTP请求或从磁盘加载共享首选项),则可以使用Future

如果有连续的事件或数据流,则可以使用Stream。不过请注意,默认情况下,Dart中的流不启用多播,这意味着只能有一个订阅者,并且该流在取消订阅时关闭。

作为使用dart异步功能的回报,您可以获得许多语言功能(async/await)和运算符以及Flutter小部件(FutureBuilder / StreamBuilder)。

另一种替代方法是InheritedWidget:它们实际上不是异步的,但是非常适合于不会频繁更改的全局状态(例如您的示例中的身份验证)。