如何避免JavaScript中的功能循环依赖关系? [英] How to avoid a functional cyclic dependency in JavaScript?
问题描述
有一种特殊的JavaScript模式一直困扰着我,而我从来没有真正想出解决该问题的正确方法。相反,我通常只是忽略它,因为99%的JavaScript解释器支持函数提升,因此不会出现运行时错误。
There's a particular JavaScript pattern that has always bothered me, and I never really figured out the proper way to solve it. Instead I usually just ignore it because 99% of JavaScript interpreters support function hoisting so no run-time errors arise.
请考虑以下内容:
function onOpen()
{
console.log("Connected!");
ws.removeEventListener("open", onOpen);
ws.removeEventListener("error", onError);
}
function onError()
{
console.log("Failed to connect!");
ws.removeEventListener("message", onMessage);
ws.removeEventListener("error", onError);
}
var ws = new WebSocket("...");
ws.addEventListener("open", onOpen);
ws.addEventListener("error", onError);
在此代码中,在 onOpen
函数中,我在代码中的 onError
下定义之前引用了 onError
。这实际上不是问题,因为 onOpen
方法直到定义了 onError
之后才会运行,但是这仍然是一种不好的做法,并且会违反 ESLint的no-use-before-define规则
In this code, within the onOpen
function, I'm referencing onError
before onError
has been defined lower in the code. This isn't actually a problem, because the onOpen
method won't run until after onError
has been defined, but it's still bad practice and trips up ESLint's no-use-before-define rule
从更广泛的意义上讲,当存在两个需要互相引用的函数时,就会出现此错误:
In a more general sense, this is an error that will arise whenever two functions exist that each need to reference each other:
function a(x) {
return x === 1 ? b(x) : 2;
}
function b(x) {
return x === 2 ? a(x) : 1;
}
是否存在消除这种循环依赖的设计模式?在我的简单通用示例中,简单的解决方案是仅具有一个函数:
Is there a design pattern for eliminating this circular dependency? In my simple generic example the easy solution is "only have one function":
function a(x) {
return x === 1 ? 1 : 2;
}
但是在绑定事件侦听器时,这并不总是可能的。
However when binding event listeners this doesn't always seem possible.
推荐答案
我认为这不是一个真正的问题,因为通常情况下一切正常。您还担心这样的事实,即在声明之前提及 onError
,但您不在乎提及 ws
。但是,如果您仍然需要解决此问题,我希望这种方法可以完成工作。
I don't think this is a real problem, because usually everything works fine. Also you worry about the fact that you mention onError
before it is declared, but you don't care about mentioning ws
. But if yous still need to solve this, I hope this approach will do the work.
var eventListenerListOnOpen = [];
var eventListListenerOnError = [];
var eventListListenerOnMessage = [];
var ws;
function removeListedEventListeners(object, eventName, eventListenerList) {
eventListenerList.forEach(function(listener) {
object.removeEventListener(eventName, listener);
});
}
function onOpen() {
removeListedEventListeners(ws, "open", eventListenerListOnOpen);
removeListedEventListeners(ws, "error", eventListenerListOnError);
}
function onError() {
removeListedEventListeners(ws, "message", eventListenerListOnMessage);
removeListedEventListeners(ws, "error", eventListenerListOnError);
}
ws = new WebSocket("...");
ws.addEventListener("open", onOpen);
eventListenerListOnOpen.push(onOpen);
ws.addEventListener("error", onError);
eventListenerListOnError.push(onError);
这篇关于如何避免JavaScript中的功能循环依赖关系?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!