Vorwort Beim Schreiben von Programmen müssen wir häufig den Fortschritt anzeigen, z. B. den Ladefortschritt, den Uploadfortschritt usw. Frage Ich schreibe eine WebGL-Anwendung und muss den Ladefortschritt während der Vorladephase der Anwendung berechnen. +-------------------------------------------------------------+ | | | Ressourcen | | | | +----------+ +-----------------+ +-----------------+ | | | Skript1 | | Modell1 | | Modell2 | | | +----------+ | | | | | | | -------------+ | | -------------+ | | | +----------+ | |model1.json | | | |model2.json | | | | | Skript2 | | +------------+ | | +------------+ | | | +----------+ | | | | | | | +------------+ | | +------------+ | | | +----------+ | | Material1 | | | | Material1 | | | | | Textur1 | | | +--------+ | | | | +--------+ | | | | +----------+ | | |Textur1| | | | | |Textur1| | | | | | | +--------+ | | | | +--------+ | | | | +----------+ | | +--------+ | | | | +--------+ | | | | | Textur2 | | | |Textur2| | | | | |Textur2| | | | | +----------+ | | +--------+ | | | | +--------+ | | | | | +------------+ | | +------------+ | | | | | | | | | | +------------+ | | +------------+ | | | | | Material2 | | | | Material2 | | | | | +------------+ | | +------------+ | | | +-----------------+ +-----------------+ | | | +-------------------------------------------------------------+ Hierbei gilt eine Prämisse: Beim Laden einer Ressource muss sichergestellt werden, dass die Ressource und die von ihr referenzierten Ressourcen alle geladen sind, bevor der Ladevorgang als abgeschlossen gilt. Klasse Asset { laden(beiFortschritt) { returniere neues Promise((auflösen) => { wenn (Typ von bei Fortschritt !== 'Funktion') { beiFortschritt = (_p) => { }; } lass loadedCount = 0; let totalCount = 10; // HINWEIS: nur zur Demo let onLoaded = () => { geladeneAnzahl++; beimFortschritt(loadedCount / totalCont); wenn (loadedCount === totalCount) auflösen(); }; Versprechen.alle( dies.refAssets.map(asset => asset.load().then(onLoaded)) ); }); } } Wenn wir nun über diese Schnittstelle verfügen und weiterhin die Form der globalen Wartung von loadedCount und totalCount verwenden, wird die Handhabung ziemlich mühsam. Prinzip Die Grundidee lautet: Teile und herrsche. Teilen Sie eine große Aufgabe in mehrere kleine Aufgaben auf, berechnen Sie dann den Fortschritt aller kleinen Aufgaben separat und führen Sie schließlich den Fortschritt aller kleinen Aufgaben zusammen, um den Gesamtfortschritt zu ermitteln. +--------------------------------------------------------------------+ | | | | | Gesamtfortschritt | | | | +---------+---------+----------+----------+----------+--------+--------+ | | | Skript1 | Skript2 | Textur1 | Textur2 | Modell1 | Modell2 | | | | (0~1) | (0~1) | (0~1) | (0~1) | (0~1) | (0~1) | (0~1) | | | +---------+---------+----------+----------+----------+--------+--------+ | | | | Modell1 | | +-------------+--------------------------+-----------+ | | | Modell1.json | Material1 | Material2 | | | | (0~1) | (0~1) | (0~1) | | | +------------------------+------------------------+ | | | Textur1 | Textur2 | | | | (0~1) | (0~1) | | | +----------+------------+ | | | | Modell2 | | +-------------+--------------------------+-----------+ | | | Modell2.json | Material1 | Material2 | | | | (0~1) | (0~1) | (0~1) | | | +------------------------+------------------------+ | | | Textur1 | Textur2 | | | | (0~1) | (0~1) | | | +----------+------------+ | | | +--------------------------------------------------------------------+ Basierend auf diesem Prinzip wird der Fortschritt implementiert, indem der aktuelle Ladefortschritt aller Ressourcen über eine Liste gespeichert und dann bei jedem Auslösen von onProgress ein Zusammenführungsvorgang ausgeführt wird, um den Gesamtfortschritt zu berechnen. var fortschreitet = [ 0, // Skript1, 0, // Skript2, 0, // Textur1, 0, // Textur2, 0, // Modell1, 0, // Modell2 ]; Funktion onProgress(p) { // TODO: Fortschritte[??] = p; Rückgabewert: progresses.reduce((a, b) => a + b, 0) / progresses.length; } Doch hier gibt es eine Schwierigkeit. Wenn der onProgress-Rückruf ausgelöst wird, woher wissen wir dann, welches Element in der Liste aktualisiert werden soll? var schreitet voran = []; Funktion add() { schreitet voran.push(0); var index = fortschreitet.länge - 1; Rückgabefunktion bei Fortschritt (p) { schreitet voran[index] = p; reduzieren(); }; } Funktion reduzieren() { Rückgabewert: progresses.reduce((a, b) => a + b, 0) / progresses.length; } Verwenden Sie Closures, um den Index der Ressourcen beizubehalten. Wenn onProgress ausgelöst wird, kann der Fortschritt des entsprechenden Elements in der Liste entsprechend dem Index aktualisiert werden. Der korrekte Fortschritt kann beim abschließenden Zusammenführen berechnet werden. prüfenMit dem folgenden Code können wir den gesamten Ladevorgang simulieren: Klasse Asset { Konstruktor(Gesamtzahl) { Dies.loadedCount = 0; dies.totalCount = Gesamtanzahl; diese.timerId = -1; } laden(beiFortschritt) { wenn (Typ von bei Fortschritt !== 'Funktion') { beiFortschritt = (_p) => { }; } returniere neues Promise((auflösen) => { this.timerId = setInterval(() => { dies.loadedCount++; beim Fortschritt (dieser.geladeneAnzahl / dieser.Gesamtzahl); wenn (dieser.loadedCount === dieser.totalCount) { LöschenInterval(diese.timerId); lösen(); } }, 1000); }); } } Klasse Fortschritt { Konstruktor(beiFortschritt) { dies.onProgress = beim Fortschritt; diese._liste = []; } hinzufügen() { diese._list.push(0); const index = this._list.length - 1; zurückgeben (p) => { diese._liste[index] = p; dies.reduzieren(); }; } reduzieren() { const p = Math.min(1, diese._list.reduce((a, b) => a + b, 0) / diese._list.length); dies.onProgress(p); } } const p = neuer Fortschritt(console.log); const asset1 = neues Asset(1); const asset2 = neues Asset(2); const asset3 = neues Asset(3); const asset4 = neues Asset(4); const asset5 = neues Asset(5); Versprechen.alles([ asset1.laden(p.add()), asset2.laden(p.add()), asset3.laden(p.add()), asset4.laden(p.add()), asset5.laden(p.add()), ]).then(() => console.log('alle Ressourcen geladen')); /** Ausgabeversprechen { <Status>: "ausstehend" } 0,2 0,3 0,366666666666666664 0,416666666666666663 0,456666666666666667 0,55666666666666668 0,6233333333333333 0,6733333333333333 0,7133333333333333 0,78 0,8300000000000001 0,869999999999999 0,919999999999999 0,96 1 alle Ressourcen geladen */ Der Vorteil dieser Methode besteht darin, dass die globale Verwaltung von loadedCount und totalCount vermieden werden kann und dieser Teil der Arbeit an die interne Verwaltung der Ressourcen zurückgegeben werden kann. Sie muss lediglich große Aufgaben zusammenführen und berechnen. Die Nachteile liegen ebenfalls auf der Hand und die onProgress-Schnittstelle muss vereinheitlicht werden. Es ist sehr schwierig, in bestehenden Projekten voranzukommen, daher ist es eher für neue oder kleine Projekte geeignet. Oben sind die Details zur JavaScript-Fortschrittsverwaltung aufgeführt. Weitere Informationen zur JavaScript-Fortschrittsverwaltung finden Sie in den anderen verwandten Artikeln auf 123WORDPRESS.COM! Das könnte Sie auch interessieren:
|
<<: Grafisches Tutorial zur Installation und Konfiguration von MySQL 5.7.21 winx64 unter Windows 10
>>: Implementierung der Header-Informationen für Nginx-Operationsantworten
Was ist ein Primärschlüssel? Ein Primärschlüssel ...
Inhaltsverzeichnis Hintergrundbeschreibung Erstel...
Inhaltsverzeichnis 1. Einweg-Wertübertragung zwis...
Der vollständige Name von NC lautet Netcat (Netwo...
Inhaltsverzeichnis JS liest Datei FileReader doku...
Es gibt zwei Möglichkeiten, Angular-Projekte mit ...
Ich werde keine weitere Zeit mit Unsinnsgerede ve...
Lasst uns gemeinsam lernen 1. Traditionelle Metho...
Ich verwende einen Platzhalter in einer Texteinga...
Globales Objekt Alle Module können aufgerufen wer...
Inhaltsverzeichnis Vorwort Text Parameter Beispie...
In Bezug auf High Performance MySQL Version 3 (Ab...
Als ich anfing, Webseiten mit XHTML CSS zu entwer...
Vor kurzem musste ich alle Felder einer verknüpft...
Vorwort Samba ist eine kostenlose Software, die d...