我有 2 个事件监听器,它们对相同的共享数据/状态进行操作。例如:
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之后执行,但从事件发射器的 Angular 来看我没有这种保证。我需要以某种方式在我的代码中实现这一点。
现在我当然可以简单地从 friendData
监听器中删除 if (sharedState.isOnline) {
并让它运行它的过程。然后,我将在两个处理程序完成后运行一个函数,并在某种程度上协调共享状态依赖关系:
emitter.on('friendStatus', (status) => {
sharedState.isOnline = status.isOnline;
reconcileStateBetweenUsernameAndIsOnline();
});
emitter.on('friendData', (friend) => {
sharedState.username = friend.username;
reconcileStateBetweenUsernameAndIsOnline();
});
问题是这个协调函数知道这个特定的数据依赖性用例;因此不能非常通用。由于存在大量相互关联的数据依赖性,这似乎更难实现。例如,我已经在处理其他订阅和其他数据依赖性,并且我的协调功能变得相当庞大和复杂。
我的问题是:有更好的方法来建模吗?例如,如果我保证处理程序将按特定顺序运行,我就不会遇到此问题。
编辑:预期的行为是使用sharedState并呈现一个UI,我希望用户名仅在状态isOnline为true时显示。
最佳答案
从@Bergi在评论中的回答来看,我暗示的解决方案似乎是最适合这种情况的。只需让事件处理程序设置自己的独立状态,然后观察值的变化并根据您需要执行的操作编写适当的逻辑即可。例如我需要显示一个用户名;该函数不应该关心顺序或了解时间:它应该简单地检查 isOnline 状态是否为 true 以及是否存在用户名。然后,只要函数的每个依赖项发生变化,就可以使用可观察模式来调用该函数。在这种情况下,该函数依赖于 status.isOnline
和 friend.username
,因此只要这些值发生变化,它就会观察并重新执行。
function showUsername() {
if (status.isOnline && friend.username != '') return true;
}
此函数必须观察
它所依赖的属性(status.isOnline 和friend.username)。您可以查看 RxJS 或其他库,以更“标准”的方式实现此目的。
关于javascript - 如何处理事件监听器和共享状态中的竞争条件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61196788/