Ankündigung

Einklappen
Keine Ankündigung bisher.

AbortController mit mehreren Fetch Abfragen via all Settled

Einklappen

Neue Werbung 2019

Einklappen
X
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • AbortController mit mehreren Fetch Abfragen via all Settled

    Per Input-EventListener auf ein Input Feld starte ich 4 zusammenhängende Fetch Abfragen mittels all Settled bei jeder Tastatureingabe, sobald mehr als 3 Buchstaben eingegeben werden :

    All Setteled damit bei einer eventuell negativen ("rejected") Abfrage trotzdem die Daten der restlichen Abfragen vorliegen.

    Code:
    async function getDataWithId(id) {
            const [customer, contact, bank, deliveryAddress] = await Promise.allSettled([getBasic(id), getContact(id), getBank(id), getDeliveryAddress(id)]);
            if (customer.status !='rejected') { weiterer Code ... }
    
        async function getBasic(id) {
            const response = await fetch(`getCustomerDetail.php?searchId=${id}`, {signal});
            return response.json();
        }
    
        async function getContact(id) {
            const response = await fetch(`getcustomerContact.php?searchId=${id}, {signal}`);
            return response.json();
        }
        async function getBank(id) {
            abortController.abort();
            const response = await fetch(`getCustomerBank.php?searchId=${id}, {signal}`);
            return response.json();
        }
        async function getDeliveryAddress(id) {
            const response = await fetch(`getCustomerDeliveryAddress.php?searchId=${id}, {signal}`);
            return response.json();
        }
    Sobald der User ins Input Feld z.B. "Sch" eintippt starten die 4 Fetch Aufrufe und ich gebe die ersten 10 Resultate dieser Datenbanksuche in ein DIV aus.
    Klappt auch alles wunderbar.
    Da man doch relativ schnell tippt ist es mein Ziel, jeweils die aktuellen Fetch Aufrufe zu stoppen, sobald der User eine weitere Tastatureingabe ins Input getätigt hat.
    Sobald er z.B. direkt nach "Sch" "Scho" eingibt, interessiert mich die vorherige Suche nach nur "Sch" ja nicht mehr und ich möchte die jeweils alte Abfrage canceln, falls diese noch nicht angeschlossen wurde,
    um direkt die neue (jeweils aktuellste) zu starten.

    Um dies zu erreichen mein Versuch :

    async function getDataWithId(id) {
    const abortController = new AbortController();
    const signal = abortController.signal;
    signal.addEventListener('abort', () => {
    console.log("Abfrage abgebrochen");
    });
    let FetchError = [];
    const [customer, contact, bank, deliveryAddress] = await Promise.allSettled([getBasic(id, signal), getContact(id, signal), getBank(id, signal), getDeliveryAddress(id, signal)]);



    Allen 4 asynchronen Funktionen gebe ich neben id noch den Parameter {signal} mit,
    um diese abbrechen zu können.

    Um zu testen hab ich mal der 3. Abfrage einen Abbruch verpasst ;
    Code:
    async function getBank(id, signal) {
            abortController.abort();
            const response = await fetch(`getCustomerBank.php?searchId=${id}, {signal}`);
            return response.json();
        }
    Das für mich sehr verwunderliche (und gleichzeitig unbrauchbare) Resultat : die beiden ersten Fetch Aufrufe laufen durch und liefern meine response zurück
    was meines Erachtens zu erwarten ist, der 3. gecancelte Aufruf der Bankdaten liefert kein Ergebnis zurück da auf abort gestellt aber selbst der vierte Fetch Aufruf der ja nach dem abort kommt
    wird noch vollständig ausgeführt und liefert alle Daten dieses Aufrufs was für mich sehr verwunderlich ist ?

    Ausserdem wird meine Konsolenausgabe "Abfrage abgebrochen" nicht ausgeführt was ich ebenfalls nicht verstehe.

    Wenn ich in der Entwicklertool in meinen Reiter Netzwerk schaue seh ich lediglich die 3 erfolgreich abgeschlossenen Resultate mit 200 Code, jedoch nicht den abgebrochenen.

    Hab auch probiert, dem 2. Parameter meiner Funktion dem signal eine geschweifte Klammer mitzugeben, also {signal}

    Jemand ne Ahnung was ich falsch mache ?


  • #2
    Ist halt so ne Sache mit der Asynchronität... bei einer echten Nebenläufigkeit sind bereits alle 4 Threads gestartet, dann kommt das abort aus dem dritten Thread (was global gelten soll, wie ich annehme) zu spät für den ebenfalls bereits laufenden, vierten Thread. Aber ehrlich gesagt hab ich keine Ahnung, ob JS hier tatsächlich echte Threads verwendet.

    Für (bzw. gegen) das Schnell-tippen könnte ein kurzer Delay nach Key-Up helfen, bevor die Suche startet. Dh. starte einen Timer nach key-up und wenn innerhalb der Wartezeit ein weiterer Key-Up kommt, refresh den Timer. 250ms sollten in der Regel ausreichen
    Über 90% aller Gewaltverbrechen passieren innerhalb von 24 Stunden nach dem Konsum von Brot.

    Kommentar


    • #3
      dann kommt das abort aus dem dritten Thread (was global gelten soll, wie ich annehme
      da haste richtig angenommen.

      Mit dem Key-Up wäre eine Alternative, 250ms sollten selbst für eine Echtzeit Suche vertretbar sein.

      Danke fürs Durchlesen und schönen Abend noch

      Kommentar


      • #4
        Hier würde sich auch RxJs anbieten mit einer debounce pipe.
        https://rxjs.dev/api/operators/debounceTime

        Kommentar

        Lädt...
        X