MobX的工作方式类似于电子表格,所有内容均源自状态。甚至具有autorun
之类的效果。
对我来说,目前尚不清楚何时基于某些事件触发而不是基于状态变化(使用autorun
或类似的东西)运行效果。
例如,我需要在满足3个特定条件(从状态派生)后获取一些牛奶(导致HTTP请求的动作-因此产生效果)。我可以使用when
来运行此副作用:
when(
() => {
if (
self.isOnConfirmationPage &&
paymentStore.successfullySubscribed &&
calendarStore.isFriday
) {
return true;
}
return false;
},
() => self.fetchMilk(),
);
出现了一项新要求,要求我添加一些日志记录。具体来说,我需要调用track()
服务(另一个HTTP请求,因此产生另一种效果),但是此track()
服务取决于fetchMilk()
服务返回的数据。
现在我可以简单地将.then()
添加到我的fetchMilk中:
self.fetchMilk().then(milkResponse => self.track(
milkResponse.user,
milkResponse.order
))
回到我的问题的标题,对我来说,这是“基于事件进行响应”-在这种情况下,事件是fetchMilk()
服务的响应。
如果我只是根据状态变化而不是事件做出反应怎么办?
这意味着track()
也需要置于反应中,并且由于它取决于fetchMilk()
的响应,因此我可以将其简单地存储在MobX存储中并对其进行反应:
when(
() => {
if (
self.milk.user &&
self.milk.order
) {
return true;
}
return false;
},
() => self.track(self.milk.user, self.milk.order),
);
请注意,我不是使用“基于承诺”的流程来处理异步行为,而是根据值的变化做出反应。
我的问题:我应该使用这两个选项中的哪个?每种方法的优点/缺点是什么?使用第二种方法对异步行为进行建模是否安全?
我会选择promise.then()
版本,只是因为遵循代码流程更容易。没有规则说必须设置应用程序中的所有内容,以便所有代码都由mobx的动作和反应来驱动。
当您希望将应用程序的更改广播传播到世界时,您将进入mobx世界。
[考虑起来,mobx就像事件分配器一样,但是事件分配代码(订阅和通知)隐藏在mobx魔术之后。因此,根据我的经验,最好的选择是完成所有需要做的异步工作,然后notify更改。
[如果您查看the official documentation,它有一个使用异步代码的示例,它确实可以做到这一点。