Detaillierte Erläuterung mehrerer Lösungen für JavaScript-Unterbrechungsanforderungen

Detaillierte Erläuterung mehrerer Lösungen für JavaScript-Unterbrechungsanforderungen

1 Versprechen

Ein Nachteil von Promise besteht darin, dass es nach seiner Erstellung nicht mehr storniert und somit grundsätzlich nicht beendet werden kann.

Aber wir können die Unterbrechung der Anfrage simulieren, indem wir die Aufrufkette oder das Promise unterbrechen.

Unterbrechen Sie die Anrufkette

Das Unterbrechen der Aufrufkette bedeutet, dass nach der Ausführung eines then/catch-Befehls nachfolgende Kettenaufrufe (einschließlich then, catch und finally) nicht mehr ausgeführt werden.

Die Methode besteht darin, eine neue Promise-Instanz in then/catch zurückzugeben und sie im ausstehenden Zustand zu halten:

neues Versprechen((lösen, ablehnen) => {
    setzeTimeout(() => {
        lösen('Ergebnis');
    });
}).dann(res => {
    // Wenn eine bestimmte Bedingung erfüllt ist, gib eine ausstehende Promise-Instanz zurück, um die Aufrufkette zu unterbrechen, if (res === 'result') {
        gib ein neues Promise zurück(() => {});
    }
    console.log(res); // kein Drucken }).then(() => {
    console.log('dann wird es nicht ausgeführt'); // kein Drucken}).catch(() => {
    console.log('catch nicht ausgeführt'); // kein Drucken}).finally(() => {
    console.log('schließlich nicht ausgeführt'); // kein Drucken});

Ein Versprechen unterbrechen

Das Unterbrechen eines Promises ist nicht dasselbe wie das Abbrechen eines Promises, da ein Promise nicht beendet werden kann.

Die Unterbrechung bedeutet hier, das ausstehende Versprechen zum richtigen Zeitpunkt abzulehnen. Ein gängiges Anwendungsszenario besteht beispielsweise darin, ein Timeout für die Netzwerkanforderung festzulegen und diese zu unterbrechen, sobald das Timeout eintritt.

Verwenden Sie wie üblich setTimeout, um Netzwerkanforderungen zu simulieren. Der Schwellenwert ist auf Math.random() * 3000 eingestellt, was bedeutet, dass das Ergebnis innerhalb von 3 Sekunden zurückgegeben wird.

const request = neues Versprechen((lösen, ablehnen) => {
  setzeTimeout(() => {
    resolve('Serverdaten empfangen')
  }, Math.random() * 3000)
})

Unter der Annahme, dass mehr als 2 Sekunden ein Netzwerk-Timeout bedeuten, können wir eine Timeout-Verarbeitungsfunktion kapseln.

Da die für Netzwerkanforderungen erforderlichen Ereignisse zufällig sind, kann die Methode Promise.race verwendet werden, um den Zweck der Timeout-Ablehnung zu erreichen.

const timeoutReject = (p1, timeout = 2000) => {
    const p2 = neues Versprechen((lösen, ablehnen) => {
        setzeTimeout(() => {
            ablehnen('Netzwerk-Timeout');
        }, Zeitüberschreitung);
    });
    gibt Promise.race([p1, p2]) zurück;
};

timeoutReject(Anfrage).dann(res => {
    konsole.log(res);
}).catch(err => {
    console.log(fehler);
});

Abbruchmethode umschließen - Axios' CancelToken imitieren

Die obige Implementierung ist nicht flexibel, da es viele Möglichkeiten gibt, Promise zu unterbrechen, und nicht nur ein Netzwerk-Timeout.

Wir können den Kernquellcode von CancelToken in Axios imitieren und einfach eine Abbruchmethode packen, die Benutzer jederzeit aufrufen können.

Funktion abortWrapper(p1) {
    abbrechen lassen;
    const p2 = neues Versprechen((lösen, ablehnen) => {
        Abbrechen = ablehnen;
    });
    // Wenn keine Lösung oder Ablehnung erfolgt, ist der Status von p2 immer „Ausstehend“
    const p = Promise.race([p1, p2]);
    p.abort = abbrechen;
    Rückgabe p;
}

const req = abortWrapper(Anfrage);
req.then(res => {
    konsole.log(res);
}).catch(err => {
    console.log(fehler);
});

setzeTimeout(() => {
    // Rufen Sie req.abort manuell auf, um den Status von p2 auf „abgelehnt“ zu ändern
    req.abort('manuelle Abbruchanforderung');
}, 2000);

Der Hauptzweck einer solchen Kapselung besteht darin, die Auflösung oder Ablehnung außerhalb des Promise steuern zu können, sodass Benutzer die Auflösung (Trigger .then) oder Ablehnung (Trigger .catch) jederzeit manuell aufrufen können.

Es ist zu beachten, dass die Promise-Anforderung zwar unterbrochen wird, das Promise jedoch nicht beendet wird und die Netzwerkanforderung möglicherweise weiterhin zurückgegeben wird. Zu diesem Zeitpunkt ist uns das Anforderungsergebnis jedoch nicht mehr wichtig.

2 RXJS-Abmeldemethode

Rxjs selbst bietet eine Methode zum Abbestellen.

let stream1$ = neues Observable(Beobachter => {
    let timeout = setTimeout(() => {
        Beobachter.next('beobachtbares Timeout');
    }, 2000);

    zurückgeben () => {
        Zeitüberschreitung löschen (Zeitüberschreitung);
    }
});
let disposable = stream1$.subscribe(Wert => console.log(Wert));
setzeTimeout(() => {
    Einweg.Abbestellen();
}, 1000);

3 Axios CancelToken

Der CancelToken von Axios kann auf zwei Arten verwendet werden:

  • Methode 1
importiere Axios von „Axios“;
const CancelToken = axios.CancelToken;
const Quelle = CancelToken.source();

axios.get('/Benutzer/12345', {
  cancelToken: Quelle.Token
}).catch(Funktion (geworfen) {
  wenn (axios.isCancel(geworfen)) {
    console.log('Anfrage abgebrochen', thrown.message);
  } anders {
    // Fehler behandeln
  } 
});

source.cancel('Vorgang vom Benutzer abgebrochen.');
  • Methode 2
importiere Axios von „Axios“;
const CancelToken = axios.CancelToken;

// Erstellen Sie eine Variable wie „cancel“, um die Methode zum Unterbrechen einer Anforderung zu speichern. let cancel;

axios.get('/Benutzer/12345', {
  cancelToken: neues CancelToken(Funktion Executor(c) {
    cancel = c; // Parameter c zum Abbrechen zuweisen
  })
});

// Bestimmen Sie, ob „Abbrechen“ eine Funktion ist und stellen Sie sicher, dass Axios ein CancelToken instanziiert hat.
wenn (Typ von Abbrechen === 'Funktion') {
    stornieren();
    abbrechen = null;
}

CancelToken-Kernquellcode: (axios/lib/cancel/CancelToken.js)

„streng verwenden“;

var Abbrechen = erfordern('./Abbrechen');

/**
 * Ein „CancelToken“ ist ein Objekt, mit dem die Stornierung einer Operation angefordert werden kann.
 *
 * @Klasse
 * @param {Function} executor Die Executor-Funktion.
 */
Funktion CancelToken(Executor) {
  wenn (Typ des Executors !== 'Funktion') {
    throw new TypeError('Executor muss eine Funktion sein.');
  }

  var lösenPromise;
  this.promise = neues Versprechen (Funktion promiseExecutor(resolve) {
    resolvePromise = lösen;
  });

  var token = dies;
  Executor (Funktion Abbrechen (Nachricht) {
    wenn (Token.Grund) {
      // Stornierung wurde bereits beantragt
      zurückkehren;
    }

    token.reason = neue Abbrechen(Nachricht);
    Versprechen auflösen(token.reason);
  });
}

/**
 * Löst eine „Abbrechen“-Meldung aus, wenn eine Stornierung angefordert wurde.
 */
CancelToken.prototype.throwIfRequested = Funktion throwIfRequested() {
  wenn (dieser.Grund) {
    wirf diesen.Grund;
  }
};

/**
 * Gibt ein Objekt zurück, das ein neues „CancelToken“ und eine Funktion enthält, die, wenn sie aufgerufen wird,
 * storniert den „CancelToken“.
 */
CancelToken.source = Funktion Quelle() {
  var abbrechen;
  var token = neues CancelToken(Funktion Executor(c) {
    abbrechen = c;
  });
  zurückkehren {
    Zeichen: Zeichen,
    abbrechen: abbrechen
  };
};

module.exports = Token abbrechen;

Es ist ersichtlich, dass die im Kernquellcode von CancelToken enthaltene Idee von Axios unten mit der Idee übereinstimmt, die oben beschriebene Abbruchmethode für die Promise-Verpackung zu unterbrechen.

Es ist nur so, dass Axios „resolve“ manuell extern aufruft (der Benutzer löst die Methode „cancel“ aus), und sobald „resolve“ aufgerufen wird, löst es die Methode „then“ von „promise“ aus. Sehen wir uns den Quellcode von „promise.then“ an: (axios/lib/adapters/xhr.js)

wenn (config.cancelToken) {
  // Abbruch behandeln
  config.cancelToken.promise.then(Funktion beiAbgebrochen(Abbrechen) {
    wenn (!Anfrage) {
      zurückkehren;
    }

    Anfrage.Abbrechen();
    ablehnen (abbrechen);
    // Anfrage bereinigen
    Anfrage = null;
  });
}

Sie können sehen, dass in der Then-Methode die Abbruchmethode ausgeführt wird, um die Anforderung abzubrechen, und Reject aufgerufen wird, um das äußere Versprechen fehlschlagen zu lassen.

Dies ist das Ende dieses Artikels über mehrere detaillierte Lösungen für JavaScript-Interrupt-Anfragen. Weitere relevante Inhalte zu JS-Interrupt-Anfragen finden Sie in früheren Artikeln auf 123WORDPRESS.COM oder in den folgenden verwandten Artikeln. Ich hoffe, dass jeder 123WORDPRESS.COM in Zukunft unterstützen wird!

Das könnte Sie auch interessieren:
  • JavaScript-Codebibliothek cookieLibrary.js, die Cookies schreibt
  • Erstellen einer JS-Codebasis von Grund auf
  • Einfache Verwendung von Java FastJson
  • Vue.js Leistungsoptimierung N Tipps (es lohnt sich, sie zu sammeln)
  • AngularJS implementiert den Beispielcode zum Erweitern und Verkleinern einiger Spalten der Tabelle
  • JavaScript implementiert die umfassendste Codeanalyse einer einfachen Lupe (ES5)
  • JavaScript zur Implementierung der umfassendsten Codeanalyse eines einfachen Karussells (objektorientiert ES6)
  • JavaScript zur Implementierung eines einfachen Karusselldiagramms, umfassendste Codeanalyse (ES5)
  • JavaScript zur Implementierung der umfassendsten Codeanalyse eines einfachen Einkaufswagens (ES6 objektorientiert)
  • 5 Möglichkeiten, Ihre JavaScript-Codebasis sauberer zu machen

<<:  Einführung in die Docker-Architektur

>>:  Detailliertes Beispiel zur Verwendung der distinct-Methode in MySQL

Artikel empfehlen

So verbinden Sie XShell und Netzwerkkonfiguration in CentOS7

1. Linux-Netzwerkkonfiguration Bevor Sie das Netz...

Methoden und Schritte für den Zugriff auf die Baidu Maps API mit JavaScript

Inhaltsverzeichnis 1. Baidu Map API-Zugriff 2. Ve...

Docker-Container-Protokollanalyse

Containerprotokolle anzeigen Verwenden Sie zunäch...

Docker erstellt CMS-On-Demand-System mit Player-Funktion

Inhaltsverzeichnis Text 1. Maschine vorbereiten 2...

Tutorial zur Installation und Konfiguration der Linux CentOS MySQL-Datenbank

Hinweise zur Installation der MySQL-Datenbank, mi...

Acht gängige SQL-Verwendungsbeispiele in MySQL

Vorwort MySQL setzte auch 2016 seinen starken Wac...

CSS-Code zur Steuerung der Hintergrundfarbe der Webseite

Ich glaube, jeder macht sich oft Sorgen, ob er Bi...

Führt das Laden von CSS zu einer Blockierung?

Vielleicht weiß jeder, dass die JS-Ausführung die...

Webdesign-Tipps für Formular-Eingabefelder

Dieser Artikel listet einige Tipps und Codes zu F...

Ursachenanalyse und Lösung des E/A-Fehlers beim Löschen einer MySQL-Tabelle

Problemphänomen Ich habe kürzlich Sysbench verwen...

xtrabackup MySQL-Datenbank sichern und wiederherstellen

Aufgrund einiger seiner eigenen Merkmale (Sperren...