VorwortKürzlich hatte ein Freund von mir ein Vorstellungsgespräch und der Interviewer stellte eine seltsame Frage, nämlich die Frage, die ich in den Titel geschrieben habe. Wenn der Interviewer diese Frage stellt, weiß er wahrscheinlich nicht viel über React. Es kann auch daran liegen, dass er gesehen hat, dass der Kandidat in seinem Lebenslauf geschrieben hat, dass er mit React vertraut ist, und der Interviewer möchte mit dieser Frage beurteilen, ob der Kandidat wirklich mit React vertraut ist 🤣. Stellt der Interviewer die richtigen Fragen? §Die Frage des Interviewers ist, ob setState eine Makrotask oder eine Mikrotask ist. Seiner Meinung nach muss setState eine asynchrone Operation sein. Um festzustellen, ob setState eine asynchrone Operation ist, können Sie zunächst ein Experiment durchführen. Erstellen Sie über CRA ein neues React-Projekt und bearbeiten Sie den folgenden Code im Projekt: importiere React von „react“; Logo aus „./logo.svg“ importieren; importiere './App.css'; Klasse App erweitert React.Component { Zustand = { Anzahl: 1000 } rendern() { zurückkehren ( <div Klassenname="App"> <Bild src={logo} alt="logo" Klassenname = "App-Logo" beiKlick={this.handleClick} /> <p>Meine Follower: {this.state.count}</p> </div> ); } } Standard-App exportieren; Die Seite sieht wahrscheinlich so aus: Das obige React-Logo ist an ein Klickereignis gebunden. Jetzt müssen wir dieses Klickereignis implementieren. Führen Sie nach dem Klicken auf das Logo eine SetState-Operation aus, drucken Sie ein Protokoll, wenn die Set-Operation abgeschlossen ist, und fügen Sie vor der Set-Operation eine Makro- und eine Mikroaufgabe hinzu. Der Code lautet wie folgt: handleKlick = () => { const Fans = Math.floor(Math.random() * 10) setzeTimeout(() => { console.log('Makroaufgabe ausgelöst') }) Versprechen.auflösen().dann(() => { console.log('Mikrotask-Trigger') }) dies.setState({ Anzahl: this.state.count + Fans }, () => { console.log('Neue Fans:', Fans) }) } Offensichtlich wird nach dem Klicken auf das Logo zuerst der SetState-Vorgang abgeschlossen und dann die Mikrotask und die Makrotask ausgelöst. Daher ist die Ausführungszeit von setState früher als die von Mikrotasks und Makrotasks. Trotzdem kann nur gesagt werden, dass seine Ausführungszeit früher als die von Promise.then ist, was nicht beweisen kann, dass es sich um eine synchrone Aufgabe handelt. handleKlick = () => { const Fans = Math.floor(Math.random() * 10) console.log('Starten') dies.setState({ Anzahl: this.state.count + Fans }, () => { console.log('Neue Fans:', Fans) }) console.log('Ende des Laufs') } Aus dieser Perspektive scheint es, dass setState auch eine asynchrone Operation ist. Der Hauptgrund ist, dass im Lebenszyklus von React und dem gebundenen Ereignisfluss alle setState-Operationen zunächst in einer Warteschlange zwischengespeichert werden. Nachdem das gesamte Ereignis beendet ist oder der Mount-Prozess beendet ist, wird die zuvor zwischengespeicherte setState-Warteschlange zur Berechnung herausgenommen, um eine Statusaktualisierung auszulösen. Sobald wir aus dem Ereignisfluss oder Lebenszyklus von React aussteigen, können wir die Kontrolle von React über setState unterbrechen. Der einfachste Weg besteht darin, setState in die anonyme Funktion von setTimeout einzufügen. handleKlick = () => { setzeTimeout(() => { const Fans = Math.floor(Math.random() * 10) console.log('Starten') dies.setState({ Anzahl: this.state.count + Fans }, () => { console.log('Neue Fans:', Fans) }) console.log('Ende des Laufs') }) } Man kann erkennen, dass sich setState im Wesentlichen noch in einer Ereignisschleife befindet und nicht zu einer anderen Makrotask oder Mikrotask gewechselt ist. Die Implementierung basiert auf synchronem Code im Betrieb, sieht aber nach asynchronem Verhalten aus. Es stellt sich also überhaupt nicht die Frage nach dem Interviewer. Wie steuert React setState? §Im vorherigen Fall wird setState nur in setTimeout zu einer synchronen Methode. Wie wird das gemacht? handleKlick = () => { // Normaler Betrieb this.setState({ Anzahl: dieser.Zustand.Anzahl + 1 }) } handleKlick = () => { // Operation außerhalb der React-Steuerung setTimeout(() => { dies.setState({ Anzahl: this.state.count + Fans }) }) } Lassen Sie uns den vorherigen Code noch einmal durchgehen. Bei diesen beiden Vorgängen zeichnen wir den Aufrufstapel jeweils einmal in „Performance“ auf, um den Unterschied zwischen den beiden Aufrufstapeln zu sehen. Im Aufrufstapel können Sie sehen, dass die Methode Component.setState schließlich die Methode enqueueSetState aufruft und die Methode enqueueSetState die Methode scheduleUpdateOnFiber aufruft. Der Unterschied besteht darin, dass die Methode scheduleUpdateOnFiber bei normalen Aufrufen nur EnsureRootIsScheduled aufruft und die Methode flushSyncCallbackQueue nach dem Ende der Ereignismethode aufgerufen wird. Beim Verlassen des React-Ereignisflusses ruft scheduleUpdateOnFiber direkt die Methode flushSyncCallbackQueue auf, nachdem der Aufruf EnsureRootIsScheduled abgeschlossen ist. Diese Methode wird verwendet, um den Status zu aktualisieren und erneut zu rendern. Funktion scheduleUpdateOnFiber(Glasfaser, Spur, Ereigniszeit) { wenn (Spur === SyncLane) { // Synchroner Vorgang EnsureRootIsScheduled(root, eventTime); // Prüfen Sie, ob es sich noch im React-Ereignisstrom befindet. // Wenn nicht, rufen Sie zum Aktualisieren direkt flushSyncCallbackQueue auf, wenn (executionContext === NoContext) { : flushSyncCallbackQueue(); } } anders { // Asynchroner Vorgang} } Der obige Code kann diesen Prozess einfach beschreiben. Er bestimmt hauptsächlich, ob der Ausführungskontext gleich NoContext ist, um zu bestimmen, ob sich der aktuelle Aktualisierungsprozess im React-Ereignisfluss befindet. Wie wir alle wissen, synthetisiert React beim Binden von Ereignissen die Ereignisse und bindet sie an das Dokument (react@17 wurde geändert, um die Ereignisse an das beim Rendern angegebene DOM-Element zu binden) und versendet sie schließlich. Wenn alle Ereignisse ausgelöst werden, wird zuerst die Methode batchedEventUpdates$1 aufgerufen, wo der Wert von executionContext geändert wird, und React weiß, dass setState zu diesem Zeitpunkt unter seiner Kontrolle steht. //Standardzustand des Ausführungskontexts var executionContext = NoContext; Funktion batchedEventUpdates$1(fn, a) { var prevExecutionContext = Ausführungskontext; executionContext |= EventContext; // Status ändern try { Rückgabewert fn(a); Endlich Ausführungskontext = vorheriger Ausführungskontext; // Nachdem der Anruf abgeschlossen ist, rufen Sie flushSyncCallbackQueue auf wenn (Ausführungskontext === KeinKontext) { : flushSyncCallbackQueue(); } } } Unabhängig davon, ob Sie „flushSyncCallbackQueue“ direkt aufrufen oder den Aufruf verschieben, ist dies im Wesentlichen synchron, es stellt sich jedoch die Frage der Reihenfolge. In Zukunft wird es asynchrones SetState geben§Wenn Sie sich den obigen Code genau ansehen, werden Sie feststellen, dass in der Methode „scheduleUpdateOnFiber“ bestimmt wird, ob die Spur synchron ist. Liegt also eine asynchrone Situation vor? Funktion scheduleUpdateOnFiber(Glasfaser, Spur, Ereigniszeit) { wenn (Spur === SyncLane) { // Synchroner Vorgang EnsureRootIsScheduled(root, eventTime); // Prüfen Sie, ob es sich noch im React-Ereignisstrom befindet. // Wenn nicht, rufen Sie zum Aktualisieren direkt flushSyncCallbackQueue auf, wenn (executionContext === NoContext) { : flushSyncCallbackQueue(); } } anders { // Asynchroner Vorgang} } Als React vor zwei Jahren seine Glasfaserarchitektur aktualisierte, bereitete es sich auf die Asynchronität vor. Der Concurrent-Modus wird offiziell in React 18 veröffentlicht. Die offizielle Einführung in den Concurrent-Modus erfolgt wie folgt. Was ist der Concurrent-Modus? Der Concurrent-Modus ist eine Reihe neuer React-Funktionen, die dazu beitragen, dass Apps reaktionsfähig bleiben und entsprechend den Gerätefunktionen und der Netzwerkgeschwindigkeit des Benutzers angemessen skaliert werden. Im Concurrent-Modus erfolgt das Rendering nicht blockierend. Es ist unterbrechbar. Dies verbessert das Benutzererlebnis. Darüber hinaus werden dadurch neue Möglichkeiten freigeschaltet, die vorher nicht möglich waren. Wenn Sie jetzt den Concurrent-Modus verwenden möchten, müssen Sie die experimentelle Version von React verwenden. Wenn Sie an diesem Teil interessiert sind, können Sie meinen vorherigen Artikel lesen: https://blog.shenfq.com/posts/2020/React%20The Evolution of Architecture%20-%20From Synchronous to Asynchronous.html ZusammenfassenDamit ist dieser Artikel darüber, ob setState in React eine Makrotask oder eine Mikrotask ist, abgeschlossen. Weitere Informationen dazu, ob setState in React eine Makrotask oder eine Mikrotask ist, finden Sie in früheren Artikeln auf 123WORDPRESS.COM oder in den folgenden verwandten Artikeln. Ich hoffe, Sie werden 123WORDPRESS.COM auch in Zukunft unterstützen! Das könnte Sie auch interessieren:
|
<<: Zusammenfassung des Wissens über MySql-Speicher-Engines und Indizes
>>: Installieren Sie Zookeeper unter Docker (Standalone und Cluster).
Inhaltsverzeichnis 1. Entdecken Sie das Problem 2...
Ich habe heute eine Aufgabe von der Firma erhalte...
Inhaltsverzeichnis 1. Installieren Sie axios 2. V...
In diesem Artikel erfahren Sie, wie Sie mysql5.7....
Das <input>-Tag Das <input>-Tag wird ...
1. Grundlegende Anwendungsbeispiele für Float 1. ...
Normalerweise verwende ich nginx als Reverse-Prox...
MySQL-Dienst stoppen Klicken Sie in Windows mit d...
Welche historische Version kann die aktuelle Tran...
Fehlermeldung: FEHLER 2002: Verbindung zum lokale...
Vorwort Als wir im vorherigen Interviewprozess na...
Autor: Guan Changlong ist DBA in der Delivery Ser...
Inhaltsverzeichnis Installieren Konfiguration Häu...
Inhaltsverzeichnis Das Prinzip und die Funktion d...
Vorwort Wenn Sie häufig über SSH auf viele versch...