Besseres Arbeitsmanagement bei Javascript Programm?

berndoa

Top Contributor
Hallo,
ich weiß dass das im Prinzip das falsche Unteforum ist aber hoffe dass man mir aufgrund der doch recht allgemeinen Frage doch helfen kann.
beim javascript Unterforum weiß ich nicht ob das da jemals Jemand sehen würde oder mitbekäme.

Ich arbeite gerade an einer Chrome Extension, programmiere also in Javascript, und habe einen "Service Worker", der ein ContentScript registriert.

Kurzum, es wird ein javascript Programm in die Webseite reingeschoben oder so.

Nur wird dieses Content Script immer unübersichtlicher weil ich diverse Aufgabenbereiche habe wie "Clicks abfangen oder Clicks tätigen"
"Werte aus der DOM ablesen" "diverse Berechnungen machen und vorhandene ariabeln updaten" "Sachen im localstorage speichern oder abrufen" etc.
Eine selbstausführende function die die Methoden von XHR Requests abändert, ist auch über dutzende Zeilen mit dabei.

Da habe ich dann dutzende Methoden, variabeln und Co.
und komme, obwohl ich noch nicht weit bin, shcon an den Punkt wo ich Methoden suchen muss, manchmal Sachen programmiere obwohl irgendwo schon eine Methode dazu gebaut habe.
Kurzum verliere den Überblick was wozu dient und was ich shcon gemacht habe, was ich angefangen habe aber noch unvollständig ist, etc.

Wie kann ich mir da die Arbeit irgendwie besser strukturieren und machen um da nicht immer mehr durcheinander zu kommen wenn das Programm noch länger wird?

Wie arbeite ich da schlicht besser und effizienter?
Wer kann mir da einen guten Tipp geben?

Insofern geht es mir auch weniger um Javascript bezogene Befehle oder sowas sondern mehr um generelle Arbeitsmethodologie.
Daher auch die Frage hier, auch wenns streng genommen nicht zum java forum gehört 🙂

Falls interesant, ich bearbeite die ganzen Dateien für die Extension schlicht im Notepad++ Editor.
 
Unabhängig von der Sprache gilt immer das Gleiche:
a) Vernünftige Arbeitsumgebung - Notepad++ bietet kaum Unterstützung - wieso nicht Visual Studio Code und co?
b) saubere Unterteilung - das geht auch in JavaScript. Hier einfach mal schauen, wie Andere das aufgeteilt haben. Es gibt ja genug Frameworks und so wo man sich sowas anschauen kann. Und teilweise wird das ja auch in Büchern behandelt.

Aber das ist ansonsten nicht mein Thema, daher bin ich damit auch schon am Ende. Aber halt noch: Immer das richtige Forum auswählen! Das gehört nicht in das Java Forum und daher auch meine Bitte, dass der Thread verschoben wird.
 
Ordnung bekommst du nur mit Javascript-ES6-Modulen. Dabei empfiehlt sich VSCode als IDE und NPM o.ä. für die Installation und Update der Module. Wir bauen Webanwendungen, da stecken mind. 6 MB JS(TS)-Code drin, das funktioniert nur so. Das ganze muss ja auch noch kompiliert und minifiziert werden, inkl. Sourcemaps, dafür empfiehlt sich dann Vite (früher wurde oft webpack verwendet). Achso, dann noch babel, eslint, SonarLint und prettier - den vielen Code muss man automatisch bearbeiten, prüfen, usw. genau wie in Java.
 
Zuletzt bearbeitet:
Unabhängig von der Sprache gilt immer das Gleiche:
a) Vernünftige Arbeitsumgebung - Notepad++ bietet kaum Unterstützung - wieso nicht Visual Studio Code und co?
b) saubere Unterteilung - das geht auch in JavaScript. Hier einfach mal schauen, wie Andere das aufgeteilt haben. Es gibt ja genug Frameworks und so wo man sich sowas anschauen kann. Und teilweise wird das ja auch in Büchern behandelt.

Aber das ist ansonsten nicht mein Thema, daher bin ich damit auch schon am Ende. Aber halt noch: Immer das richtige Forum auswählen! Das gehört nicht in das Java Forum und daher auch meine Bitte, dass der Thread verschoben wird.
In Java würde man ein großes Programm ja in zig klassen verteilen und so.
Hat Javascript da auch ein ähnliches Äquivalent wie man Methoden und Co. irgendwie sinnvoll "verteilen" kann oder so,
um da mehr Überblick und Ordnung zu halten?

Wobei, wie ja auch in java, dann das Problem kommt, dass jedes Objekt eienr Klasse auf die Sachen der anderen Klassen zugreifen können muss...
 
In JS schreibt man auch Klassen, diese werden in Namespaces organisiert. Namespaces sind im Prinzip eine Ordnerstruktur wie in Java die Packages. Es wird genauso mit "import" gearbeitet. Das funktioniert auch, wenn man keine Klassen verwenden möchte.
JS bietet aber kein Äquivalent zu "private" an. Man verwendet zwei Unterstriche als Präfix. Also __meineFunction=()=> {...} sagt nur, dass die Funktion als privat gedacht ist - sie ist es aber nicht wirklich.
 
Zuletzt bearbeitet:
Evtl. einfach mal paar Links zu dem Thema Klassen in JavaScript:

Generell macht es aber auch durchaus Sinn, statt JavaScript z.B. TypeScript zu verwenden. Das wurde ja entwickelt, um gewisse Dinge, die JavaScript eben nicht hat, doch zu bekommen.
 
Bin jetzt mal dazu übergegangen, Klassen zu benutzen,
die allerdings in der selben Datei definiert sind.
Schlechter Stil, ich weiß aber so kann ich von innerhalb der Klasse auf die globalen variabeln in der Datei zugreifen (was Javascript fast schon geiler als java macht, wenn man mal die Sicherheitssache ignoriert).
 
Bin jetzt mal dazu übergegangen, Klassen zu benutzen,
die allerdings in der selben Datei definiert sind.
Schlechter Stil, ich weiß aber so kann ich von innerhalb der Klasse auf die globalen variabeln in der Datei zugreifen (was Javascript fast schon geiler als java macht, wenn man mal die Sicherheitssache ignoriert).
Was soll man noch sagen, man kann nur warnen.
Auf den ersten Blick mag es so aussehen, als ob globale Variablen einfach zu verwenden sind und bequemer sind als lokale Funktionen und block-scoped oder local scoped Variablen. Die Wahrheit ist jedoch, dass die Verwendung globaler Variablen so weit wie möglich minimiert werden sollte. Denn sobald eine globale Variable deklariert ist, kann sie leicht von jeder nachfolgenden Funktion oder jedem Block innerhalb des Skripts oder mehrerer Skripte geändert werden, und jeder Variablenname kann versehentlich falsch geschrieben werden, was insbesondere bei großen Codebasen zu Problemen bei der Fehlersuche führt.

Um dem entgegenzuwirken, ist es immer empfehlenswert, wenn möglich lokale Variablen zu verwenden. So können mehrere Funktionen oder Blöcke lokal definierte Variablen mit demselben Namen haben, ohne dass es zu Konflikten kommt, was wiederum zu einer geringen Fehlerwahrscheinlichkeit führt.

Zweitens dauert es länger, bis Javascript globale Variablen "findet" als lokale Variablen. Der Geschwindigkeitsunterschied ist nicht riesig, aber er ist vorhanden.

Angenommen, in einer Datei wird eine globale Variable deklariert, dann kann nur diese Datei diese globale Variable verwenden und wenn wir diese globale Variable in einer anderen Datei benötigen, dann wird sie die globale Variable dieser Datei. Die Änderungen wirken sich nicht auf eine andere Datei aus.
Javascript:
//main.js
var globalVariable=20;
module.exports=globalVariable;

//file.js
let newGlobalVariable=require('./main.js');
newGlobalVariable+=10;
console.log(newGlobalVariable);

// Output
// 30
Hier gibt kein Problem, denn die Änderungen, die wir in einer Datei vornehmen, wirken sich nicht auf eine andere Datei aus.
 
Mittlerweile mag ich Javascript nicht mehr wirklich.
Nicht wegen der globalen Variabeln sondern einfach weil es so extrem umständlich ist , es hinzukriegen dass die Codeausführung an bestimmten punkten einfahc mal anhält und abwartet bis ein click oder ähnliches passiert ist.
Da muss man dann mit sync und async sachen rumhantieren, fetch udn co und weiß nie wirklich was er in welcher reihenfolge macht.
ausser man haut vor sprichwörtlich alles ein await davor, dann mauss man aber cosntructor und co auch wieder async machen was man gar nicht so wirklich darf...

nur weils irgendwer intelligent fand, dass ein thread für javascript ausreichen würde.

In java und anderen sprachen muss man gar keine sorgen habend ass code NICHT in der reihenfolge ausgeführt werden würde, wie er da steht...
 
Mir fiel das am Anfang auch schwer, so schlimm ist es aber eigentlich gar nicht. Wenn man Promises verwendet ist das verständlicher als async/await. Eine Reihenfolge gibt es bei fetch so nicht, das ist eben asynchron.
Die allermeisten Webseiten sind nicht CPU-intensiv, sondern I/O-intensiv. Das heißt, die Recheneinheiten langweilen sich, während die Seite auf Antwort vom Server oder Interaktionen des Nutzers wartet. Async nutzt diese Wartezeit. So ist normalerweise ein Thread ausreichend. Für die Ausnahmen gibt es Worker. Damit eine Website immer schön zügig auf Nutzereingaben reagiert und nicht „hängt“, braucht man also nicht mehr oder schnellere CPUs. Stattdessen braucht man eine Möglichkeit, auch dann auf Nutzereingaben zu reagieren, wenn die Website gerade auf etwas anderes wartet.

Schlimmes Javascript:
Javascript:
const r1 = new XMLHttpRequest();
const r2 = new XMLHttpRequest();
r1.open("GET", "/url.txt");
r1.addEventListener("load", () => {
  const url = r1.responseText;
  r2.open("GET", url);
  r2.addEventListener("load", () => {
    const text = r2.responseText;
    console.log(text);
  });
  r2.send();
});
r1.send();

Einfach schnell und elegant (macht das selbe wie oben):
Javascript:
fetch("/url.txt")
  .then(f1 => f1.text())
  .then(url => fetch(url))
  .then(f2 => f2.text())
  .then(text => console.log(text));
 
Nur wikll ich gar nicht dass Javscript shcon irgendeinen Mist aus Zeile 2000 macht während es eigentlich auf das Ende der Bearbeitung von Zeile 5 warten soll.

Den Msit gibts doch in java auch nicht, dass aus hirnlosen Gründen einfach mal zeile 3 vor Zeile 2 bearbeitet wird?

Gut, in java gibts erst gar keine eventlistener aber das ganze Promise gequacke ist einfahc nur dämlich.
Da will man eine simple Abfolge von Kommandos und das Programm lässt sich nicht mal gescheit anhalten wenn man es gebrauchen könnte.

Ich will an sich was ganz primitives wie:

Javascript:
for(const a in array){
  console.log("a");
  //wait for click event to be captured
  console.log("b");
}

Kriegste nicht gescheit hin in javascript.
da wird dann b auf die konsole gedruckt oder womöglich gar shcon die nächste iteration gemaht obohl der click aus der vorherigen ieration, auf den javascript warten sollte, noch nicht mal da ist.

klar geht da was mit await.

Dann darf man aber vor so gut wie alles await klatschen und praktisch alles muss plötzlich async sein.
irgendwie irgendwo irgendwann mal ein await sleep() oder sowas vorkam.

und javarotz ohne await überall meint, es könnte code einfach überspringen oder 5 zeilen, die hitnereinander stehen, auch mal gleichzeitig oder gar in willkürlicher reihenfolge abarbeiten.

Schön dass man damit in der DOM rumwerkeln kann, aber die pfuscherlösung mit promises, statt den dreck einfahc mehrthreadig zu machen wie andere gescheite sprachen, bringt es nicht wirklich.

ob ich jetzt mit await/async arbeite oder ne fetch then kette baue, ändert nicht viel.
 
So richtig verstehe ich dein Problem vermutlich nicht. Du willst eine Schleife über ein Array und jedes mal wenn ein Event ausgelöst wird, dann soll die Schleife einen Durchgang weiter laufen.
HTML:
<button id="1">
Test 1
</button>

<button id="2">
Test 2
</button>
Javascript:
const myBusiness = {
  index: 0,
  array: ['a','b','c','d'],
  action: function(buttons) {
    if (this.index < this.array.length) {
        console.log(this.array[this.index++]);
        return true;
    }
    buttons.forEach(b=> b.disabled = true);
    return false;
  }
};

const buttons = [
  document.getElementById("1"),
  document.getElementById("2")
];
buttons.forEach(b=> b.addEventListener("click", () => myBusiness.action(buttons)));
Also nur mal schnell so ohne Aufwand und viel nachzudenken. Das geht noch viel besser, wenn ich mal so drüber schaue.
 
So richtig verstehe ich dein Problem vermutlich nicht. Du willst eine Schleife über ein Array und jedes mal wenn ein Event ausgelöst wird, dann soll die Schleife einen Durchgang weiter laufen.
HTML:
<button id="1">
Test 1
</button>

<button id="2">
Test 2
</button>
Javascript:
const myBusiness = {
  index: 0,
  array: ['a','b','c','d'],
  action: function(buttons) {
    if (this.index < this.array.length) {
        console.log(this.array[this.index++]);
        return true;
    }
    buttons.forEach(b=> b.disabled = true);
    return false;
  }
};

const buttons = [
  document.getElementById("1"),
  document.getElementById("2")
];
buttons.forEach(b=> b.addEventListener("click", () => myBusiness.action(buttons)));
Also nur mal schnell so ohne Aufwand und viel nachzudenken. Das geht noch viel besser, wenn ich mal so drüber schaue.
ich will dass er einen string druckt, auf click event warten, string druck, click event warten, etc.pp.
für jedes element eines arrays die abfolge "string drucken, dann abwarten bis click event passiert".

fürdas "auf string warten" habe ich nun eine komische funktion waitForClickOnEvent, das ein neues promise returned dass auf ner bestimmten canvas einen eventlistener baut und IN diesem eventlistener, also dann wenn ein click passiert, wird bestimmter code ausgeführt, der eventlistener entfernt und das promise "resolved", kurzum das hier:
Javascript:
function waitForCustomEvent(eventName) {
  return new Promise(resolve => {
    const listener = () => {
      window.removeEventListener(eventName, listener);
      resolve();
    };
    window.addEventListener(eventName, listener);
  });
}


Nur muss ich jetzt bei den "auf click event warten" zeilen ein
Javascript:
await waitForClickOnElement();
schreiben.
weshalb die umgebende Funktion async sein muss.
wird nun irgendwo diese umgebende Funktion aufgerufen, muss die auch wieder async sein und beim aufruf wieder awaited werden.

kurzum, wegen 1,2 oder 3 einzelnen await irgendwo im code muss am Ende ALLES async sein und awaited werden.
Was aber mal so richtig sch...lecht ist.
da muss ich Konstruktoren, Funktionen, Alles async machen.
Weil fast Alles mit Allem irgendwie verzahnt ist.

Await ist wie eine Seuche, durhc die Alles mit gezwungenen async/await verpestet wird.

Aber ohne async/await und Promises gehts ja nicht weil bei sowas Simplem wie
Javascript:
while(waitMode){
//warten bis click event passiert und dort waitMode auf false gesetzt wird
}
trotz eventuell passierendem Event das Event nicht behandelt weil man ja in der Endlosschleife steckt und erst die "fertig" sein muss bevor das event gehandhabt wird.
Egal wann das Event kam, beim singlethread javascript lässt man sich ja nicht unterbrechen :-/
 
Naja da würde mein Beispiel ja passen. Immer wenn ein click auf einen der Buttons passiert wird das nächste Element des Arrays ausgegeben.
 
Ich will an sich was ganz primitives wie:

Javascript:
for(const a in array){
  console.log("a");
  //wait for click event to be captured
  console.log("b");
}

Kriegste nicht gescheit hin in javascript.
Das geht in Java btw genausowenig, auch da gibt es für die UI nur einen einzigen Thread.

Da kann man anders damit umgehen als in JS, aber das "richtig" zu machen ist da nicht unbedingt einfacher.
 
Nur ist mein Code mit Klassen und CO ziemlich komplex.
Da ALLES was zwischen 2 Klicks passiert zusammenzusuchen in in den Eventhandler zu packen, falls das überhaupt möglich ist....
 
Du bist doch sosnt immer der Klassenfan.
Und nun soll ichb Alles durcheinander schmeissen damits im Eventhandler untergebracht werden kann? 🙂
 
Ich habe mich nicht gegen Klassen ausgesprochen sondern für eine bessere Struktur. Alles, was Du geschrieben hast, deutet für mich darauf hin, dass es nicht oder zumindest nicht richtig strukturiert ist. Aber da wir keine Details haben, ist das natürlich nicht sicher zu sagen und daher können wir auch keine Hinweuise zu Verbesserungen geben.
 
Ich fürchte , mein Problem hat sich shcon dadurch erledigt dass mein Grundvorgehen nicht klappt.
Die Clicks auf die Canvas werden zwar von meinem Eventlistener mit bekommen, aber die Canvas selbst reagiert nicht drauf.
wenn ich händisch draufklicke wird reagiert aber das reingejagte Clickevent bewirkt nichts. Und ich habe keinen wirklichen Plan warum oder ob sich das fixen lässt :-(
 

Zurück
Oben