如何处理事件侦听器和共享状态中的竞争条件? [英] How to deal with race conditions in event listeners and shared state?

查看:111
本文介绍了如何处理事件侦听器和共享状态中的竞争条件?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有2个事件侦听器,它们在相同的共享数据/状态下运行.例如:

I have 2 event listeners that operate on the same shared data/state. For instance:

let sharedState = {
  username: 'Bob',
  isOnline: false,
};

emitter.on('friendStatus', (status) => {
  sharedState.isOnline = status.isOnline;
});

emitter.on('friendData', (friend) => {
  if (sharedState.isOnline) {
    sharedState.username = friend.username;
  }
});

我的问题是这些事件以任何顺序发出. friendData事件可能在friendStatus之前出现.但是friendData会对friendStatus返回的数据进行某些处理.换句话说:我需要friendData的事件处理程序在之后 friendStatus之后执行,但是从事件发射器的角度来看,我没有这种保证.我需要以某种方式在我的代码中实现它.

My problem is that these events are emitted at any order. The friendData event might come in before the friendStatus. But friendData does something with the data returned from friendStatus. In other words: I need the event handler for friendData to execute after friendStatus, but I don't have this assurance from the event emitter perspective. I need to somehow implement this in my code.

现在,我当然可以简单地将if (sharedState.isOnline) {friendData侦听器中删除,并使其正常运行.然后,在两个处理程序完成之后,我将运行一个函数,并在某种程度上调和共享状态的依赖关系:

Now of course I could simply remove the if (sharedState.isOnline) { from the friendData listener and let it run its course. Then I'd have a function run after both handlers have finished and somewhat reconciliate the shared state dependencies:

emitter.on('friendStatus', (status) => {
  sharedState.isOnline = status.isOnline;
  reconcileStateBetweenUsernameAndIsOnline();
});

emitter.on('friendData', (friend) => {
  sharedState.username = friend.username;
  reconcileStateBetweenUsernameAndIsOnline();
});

问题是此协调功能知道此特定数据依赖关系用例;因此不能很通用.对于大的互连数据依赖性,这似乎很难实现.例如,我已经在处理其他订阅和其他数据依赖项,对帐功能变得非常庞大和复杂.

Problem is that this reconciliation function knows about this specific data dependencies use case; hence cannot be very generic. With large interconnected data dependencies this seems a lot harder to achieve. For instance I am already dealing with other subscriptions and other data dependencies and my reconciliation function is becoming quite large and complicated.

我的问题是:是否有更好的方法对此建模?例如,如果我保证处理程序将以特定的顺序运行,那么我就不会遇到这个问题.

My question is: is there a better way to model this? For instance if I had the assurance that the handlers would run in a specific order I wouldn't have this issue.

编辑:预期的行为是使用sharedState并呈现一个UI,在该UI中,如果状态isOnline为true,则仅希望用户名显示.

EDIT: expected behavior is to use the sharedState and render a UI where I want the username to show ONLY if the status isOnline is true.

推荐答案

根据@Bergi在评论中的回答,我暗示的解决方案似乎最适合这种情况.只需让事件处理程序设置自己的独立状态,然后观察值的变化并根据您需要执行的操作编写适当的逻辑即可.例如,我需要显示一个用户名;该函数不必关心顺序或对时间有任何了解:它应该只检查isOnline状态是否为true以及是否有用户名.然后,只要函数的每个依赖项发生变化,就可以使用可观察模式来调用此函数.在这种情况下,该函数取决于status.isOnlinefriend.username,因此只要这些值发生更改,它将观察并重新执行.

From @Bergi's answer in the comments the solution I was hinting seems to be the most appropriate for such case. Simply let the event-handlers set their own independent state, then observe on the values changing and write appropriate logic based on what you need to do. For instance I need to show a username; this function shouldn't care about the order or have any knowledge of time: it should simply check whether the isOnline status is true and if there's a username. Then the observable pattern can be used to call this function whenever each dependency of the function changes. In this case the function depends on status.isOnline and friend.username hence it will observe and re-execute whenever those values change.

function showUsername() {
  if (status.isOnline && friend.username != '') return true;
}

此函数必须observe它依赖的属性(status.isOnline和friend.username).您可以查看RxJS或其他库,以更标准"的方式实现此目标.

This function must observe the properties it depends on (status.isOnline and friend.username). You can have a look at RxJS or other libraries for achieving this in a more "standard" way.

这篇关于如何处理事件侦听器和共享状态中的竞争条件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆