mardi 18 décembre 2018

How to avoid a functional cyclic dependency in 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.

Consider the following:

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);

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.

Aucun commentaire:

Enregistrer un commentaire