Themabewertung:
  • 0 Bewertung(en) - 0 im Durchschnitt
  • 1
  • 2
  • 3
  • 4
  • 5
Await Hell vermeiden bzw. sync function trotz await drin bauen?
#1
Hallo,
ich hoffe inständig mich kann Jemand von meinem Leiden erlösen... oder mir zumindest Rat geben :-)

Folgendes :
Ich werkle an einer Chrome Extension für eine Rouletteseite rum und es hapert am Javascriptpart.
die manifest.json und direkt extension bezogenen sachen sind nicht das Problem (bis jetzt).

Konkret habe ich einerseits einen eventlistener auf einem canvas element eingebaut.

zum anderen habe ich mittels
Code:
(function(xhr) {
    var XHR = XMLHttpRequest.prototype;
    var open = XHR.open;
    var send = XHR.send;
    var setRequestHeader = XHR.setRequestHeader;

    XHR.open = function(method, url) {
        this._method = method;
        this._url = url;
        this._requestHeaders = {};
        this._startTime = (new Date()).toISOString();

        return open.apply(this, arguments);
    };

    XHR.setRequestHeader = function(header, value) {
        this._requestHeaders[header] = value;
        return setRequestHeader.apply(this, arguments);
    };

    XHR.send = function(postData) {

...
})(XMLHttpRequest);
abgeändert, was bei Auftauchen einer XMLHttpRequest passiert.
Konkret werden darin, abhängig vom Inhalt dees Response Bodys, diverse globale Variabeln sowie Attribute mancher Objekte geändert.


Jetzt versuche ich verzweifelt, abseits davon, einen in der Theorie simplen Codeblock hinzukriegen, eine Art "Controls Setup" wie man in aus diversen games kennt:

Gegeben ein String Array.

Gehe die Elemente des Arrays der Reihe nach durch  (for loop halt)
und mache für jedes diese 3 Schritte:
1. ändere den innerText eines bestimmten divs auf das String Element ab (Damit auf der Seite sowas wie "Drücke schießen Taste" steht)
2. Warte bis ein click erfolgt.
3. nutze koordinaten des klicks, zusammen mit dem element string, um beides in einer liste zu speichern

Damit ich am Ende vom Lied eine Liste von Strings mit zugehörigen x,y koordinaten habe.
Schritt 1 ist mehr nutzerfreundlichkeit, dmait man weiß worauf man als nächstes klicken soll.

simpel in der theorie, oder?

problem nur:
ich habe keine Ahnung wie ich schritt 2 hinbekomme.
vor allem, dass javascript nicht einfach mit der näcshten iteration oder so weitermacht bevor der gerade benötgte klick reingekommen ist.
Ginge es nur drum 2 sekunden zu warten, könnte man ein await sleep() mit passender async sleep function und settimeout darin nutzen.

Aber wie wartet man bitte auf das geschehen eines clicks bzw. dass der zugehörige eventlistener abfeuert?



------------------------------------------------------------------------------------------------------------------------------------------------
Der aktuelle (Fehl?)versuch:

Ich wollte mir vom allmächtigen Chatgpt helfen lassen und habe nun folgendes gemacht:

Im click eventlistener, sowie im passenden Teil des xhr konstrukts,
werden erst die  dortigen befehle wie bisher ausgeführt und zum abschluss ein customevent  mit passendem namen gebaut und mit dispatchevent() auf den weg geschickt.
Heißt also, je nachdem was passiert (click, xhr request mit "hund" im responsebody, etc.), wird ein ganz bestimtmes customevent getriggert.


Dann habe ich noch eine neue funktion gebaut bzw. chatgpt hat gebaut:
Code:
function waitForCustomEvent(eventName) {
  return new Promise(resolve => {
    const listener = () => {
      window.removeEventListener(eventName, listener);
      resolve();
    };
    window.addEventListener(eventName, listener);
  });
}

die man aufrufen kann und die Alles anhält solange bis dieses ganz bestimmte customevent pasiert. vorher passiert nix neues mehr.


Nun sagt die Theorie dass ich bspw. sowas machen kann:
Code:
async A(){
  console.log("1");
  await waitForCustomEvent("click");
  console.log("2);
}


mit await A() sollte nun folgendes passieren:
erst wird 1 gedruckt auf die konsole.
dann sind wir am punkt wo wir einen click abwarten wollen.
dann wird also waitforcustmevent("click") ausgeführt, es wird also auf das window element ein orübergehender event listener geklatscht und gewartet bis ein click erfolgt, dann wird der eventlistener wieder entfernt.
dann wird die nächste zeile in A ausgeführt, also "2" auf die konsole gedruckt.

So sollte es in der theorie möglich sein, mitten zwischen (sync) code zeilen überall diese zeile einzubauen und der code hält dort an und läuft nicht weiter bis der click da ist. kurzum,  zwangsweise den code anhalten bis ein bestimmtes customevent reingekommen ist.
Gleiches im prinzip mit den httprequests, nur heißen dort die customevents anders.

funcktioniert das generell so?
chatgpt braucht man nicht fragen, das sagt immer "You are right, I was wrong" egal was man fragt.

Und ein daraus aber wieder resultierendes problem:
da await drin vorkommt, ist A folglich async und wir müssen wiederum await beim Aufruf von A davor packen.
Was die Funktion, die A aufruft, auch wieder async macht.

Dadurch muss ich faktisch ALLES in meinem code async machen, constructor,  funktionen ,etc. pp.

Weil halt auf Umwegen Alles Alles andere früher oder später mal aufruft.

Gibts da einen Weg das zu umgehen?

weil mir ja eigentlich nur wichtig ist, dass der code genau an den stellen anhält wo ich auf das bestimmte custom event warte.
der rest kann ja ruhig synchron laufen.

nur zwingt mich ein einzelnes await ja schon ,alles von ganz unten bis ganz oben in der funktionenaufrufhierarchie async zu machen und zu "awaiten".

chatgp konnte keine wirkliche Lösung nennen ausser "lass das await weg. dann hast du halt aber ein promise und noch keinen Wert, das du später dann doch awaiten musst". 
also keine lösung.

Kann mir bitte Jemand helfen? :-)


wie komme ich aus dem await/async zykus raus? :-(
Zitieren


Gehe zu:


Benutzer, die gerade dieses Thema anschauen:
1 Gast/Gäste