Heim >Web-Frontend >js-Tutorial >Vorladende Bilder parallel zu Versprechungen
Kernpunkte
Promise.all()
-Methode verwenden, um ein Versprechen für jede Gruppe zu erstellen, die nach allen Versprechen im Array analysiert wird. In diesem Artikel wird ein bestimmtes Problem erörtert: Wie eine große Anzahl von Bildern parallel vorlädt. Ich hatte dieses Problem in letzter Zeit und fand es schwieriger als erwartet und habe viel davon gelernt. Lassen Sie mich zunächst die Szene kurz beschreiben. Angenommen, es gibt mehrere "Gruppen" auf der Seite. Im Großen und Ganzen ist eine Gruppe eine Sammlung von Bildern. Wir möchten Bilder für jede Gruppe vorladen und wissen, wann Bilder für eine Gruppe geladen werden. Zu diesem Zeitpunkt können wir jeden gewünschten Code frei ausführen, z. B. Hinzufügen einer Klasse zur Gruppe, Ausführung einer Bildsequenz, Aufzeichnung von etwas usw. Das klingt zunächst einfach, sogar sehr einfach. Sie haben jedoch wahrscheinlich ein Detail wie ich übersehen: Wir möchten, dass alle Gruppen parallel geladen werden, nicht nacheinander. Mit anderen Worten, wir möchten nicht alle Bilder von Gruppe 1 laden, dann alle Bilder von Gruppe 2, dann alle Bilder von Gruppe 3 und so weiter. Tatsächlich ist dies nicht ideal, da es einige Gruppen geben wird, die irgendwann darauf warten müssen, dass die vorherige Gruppe abgeschlossen ist. Wenn also in einem Szenario die erste Gruppe Dutzende von Bildern hat und die zweite Gruppe nur ein oder zwei Bilder hat, müssen wir warten, bis die erste Gruppe vollständig geladen wird, bevor wir die zweite Gruppe vorbereiten können. Das ist nicht gut. Wir können definitiv besser machen! Unsere Idee ist es also, alle Gruppen parallel zu laden, so dass wir, wenn eine Gruppe vollständig geladen ist, nicht auf andere Gruppen warten müssen. Dazu ist die allgemeine Idee, das erste Bild aller Gruppen zu laden und dann das zweite Bild aller Gruppen zu laden und so weiter, bis alle Bilder vorinstalliert sind. OK, beginnen wir zunächst ein Markup, damit wir uns einig sind, was los ist.
In diesem Artikel gehe ich übrigens davon aus, dass Sie mit dem Konzept des Versprechens vertraut sind. Wenn dies nicht der Fall ist, schlage ich vor, dass Sie diesen Artikel lesen.
Tags
Aus Sicht des Tags ist eine Gruppe nichts anderes als ein Element (z. B. eine Div) mit einer Deckklasse, damit wir sie lokalisieren können, und eine Data-Images-Eigenschaft, die eine Reihe von Bild-URLs enthält (als JSON ).
<code class="language-html"><div class="deck" data-images='["...", "...", "..."]'>...</div> <div class="deck" data-images='["...", "..."]'>...</div> <div class="deck" data-images='["...", "...", "...", "..."]'>...</div></code>
Vorbereitung
In JavaScript ist dies - wie erwartet - etwas kompliziert. Wir werden zwei verschiedene Dinge erstellen: eine Gruppe Klasse (bitte legen Sie dies zwischen sehr großen Zitaten und wählen Sie den Begriff nicht aus) und ein -Preiloader Tool. Da der Voroader alle Bilder aller Gruppen kennen, um sie in einer bestimmten Reihenfolge zu laden, muss er unter allen Gruppen geteilt werden. Eine Gruppe kann keine eigene Voroader haben, andernfalls haben wir das erste Problem: Der Code wird nacheinander ausgeführt, was nicht das ist, was wir wollen. Wir brauchen also eine Voroaderin, die für jede Gruppe übergeht. Letzterer fügt sein Bild zur Warteschlange des Voroaders hinzu, und sobald alle Gruppen ihre Elemente zur Warteschlange hinzufügen, kann der Voroader mit dem Vorladen beginnen. Der Code -Ausführungs -Snippet lautet wie folgt:
<code class="language-javascript">// 实例化一个预加载器 var ip = new ImagePreloader(); // 从DOM获取所有组 var decks = document.querySelectorAll('.deck'); // 遍历它们并为每个组实例化一个新的组,将预加载器传递给每个组,以便组可以将它的图片添加到队列中 Array.prototype.slice.call(decks).forEach(function (deck) { new Deck(deck, ip); }); // 一旦所有组都将它们的项目添加到队列中,就预加载所有内容 ip.preload();</code>
Ich hoffe bisher, das macht Sinn!
bauen Sie Gruppe
Abhängig davon, was Sie mit der Gruppe tun möchten, kann diese "Klasse" ziemlich lang sein. Für unser Szenario müssen wir nur eine geladene Klasse zum Knoten hinzufügen, nachdem sein Bild geladen wurde. In der Deckfunktion gibt es nicht viel zu tun: 1. Laden Sie die Daten (aus der Eigenschaftseigenschaft). ist vorinstalliert.
<code class="language-javascript">var Deck = function (node, preloader) { // 我们从`data-images`属性获取并解析数据 var data = JSON.parse(node.getAttribute('data-images')); // 我们调用预加载器的`queue`方法,将数据和回调函数传递给它 preloader.queue(data, function () { node.classList.add('loaded'); }); };</code>
Bisher läuft es gut, nicht wahr? Das einzige, was noch übrig ist, ist der Voroader, obwohl er auch der komplexeste Teil des Codes in diesem Artikel ist.
Erstellen Sie einen Voroader
Wir wissen bereits, dass unser Voroader eine Warteschlangenmethode benötigt, um die Bildsammlung zur Warteschlange hinzuzufügen, und eine Vorspannungsmethode, um die Vorspannung zu starten. Es erfordert auch eine Helferfunktion, um das Bild vorzuladen, das als Vorspannung bezeichnet wird. Beginnen wir hier:
<code class="language-javascript">var ImagePreloader = function () { ... }; ImagePreloader.prototype.queue = function () { ... } ImagePreloader.prototype.preloadImage = function () { ... } ImagePreloader.prototype.preload = function () { ... }</code>
Der Voroader benötigt eine interne Warteschlangeneigenschaft, um die Gruppen zu halten, die sie vorladen muss, und deren jeweiligen Rückrufe.
<code class="language-javascript">var ImagePreloader = function () { this.items = []; }</code>
Elemente ist ein Array von Objekten, wobei jedes Objekt zwei Tasten enthält: - Die Sammlung enthält die zu vorgeladene Bild -URLs.
Damit können wir die Warteschlangenmethode schreiben.
<code class="language-html"><div class="deck" data-images='["...", "...", "..."]'>...</div> <div class="deck" data-images='["...", "..."]'>...</div> <div class="deck" data-images='["...", "...", "...", "..."]'>...</div></code>
okay. Zu diesem Zeitpunkt kann jede Gruppe ihr Bild zur Warteschlange hinzufügen. Wir müssen jetzt die Vorspannungsmethode erstellen, die für die tatsächliche Vorspannung des Bildes verantwortlich ist. Bevor wir jedoch zum Code springen, gehen wir zurück, um zu verstehen, was wir tun müssen. Unsere Idee ist es nicht, alle Bilder jeder Gruppe eins nach dem anderen zu laden. Unsere Idee ist es, das erste Bild jeder Gruppe, dann das zweite Bild, dann das dritte Bild und so weiter vorzuladen. Vorlast Ein Bild bedeutet, ein neues Bild mit JavaScript (mit New Image ()) zu erstellen und ein SRC darauf anzuwenden. Dadurch wird der Browser aufgefordert, die Quelle asynchron zu laden. Aufgrund dieses asynchronen Prozesses müssen wir ein Versprechen registrieren, das nach dem Download des Browsers die Ressource analysiert wird. Grundsätzlich ersetzen wir jede Bild -URL in unserem Array durch ein Versprechen, das nach dem Laden des Browsers das angegebene Bild analysiert. Zu diesem Zeitpunkt können wir Promise verwenden. Dies gilt für jede Gruppe. Beginnen wir mit der Voroadenmethode:
<code class="language-javascript">// 实例化一个预加载器 var ip = new ImagePreloader(); // 从DOM获取所有组 var decks = document.querySelectorAll('.deck'); // 遍历它们并为每个组实例化一个新的组,将预加载器传递给每个组,以便组可以将它的图片添加到队列中 Array.prototype.slice.call(decks).forEach(function (deck) { new Deck(deck, ip); }); // 一旦所有组都将它们的项目添加到队列中,就预加载所有内容 ip.preload();</code>
jetzt ist die Vorspannungsmethode. Es macht zwei Dinge (daher könnte es möglich sein, sich in zwei verschiedene Funktionen aufzuteilen, aber das liegt nicht im Rahmen dieses Artikels): 1. Es befindet sich in einer bestimmten Reihenfolge (das erste Bild jeder Gruppe, dann die zweite, dann dort ist der dritte ...) alle Bild -URLs durch Versprechen ersetzen;
<code class="language-javascript">var Deck = function (node, preloader) { // 我们从`data-images`属性获取并解析数据 var data = JSON.parse(node.getAttribute('data-images')); // 我们调用预加载器的`queue`方法,将数据和回调函数传递给它 preloader.queue(data, function () { node.classList.add('loaded'); }); };</code>
Das ist es! Schließlich ist es nicht so kompliziert, stimmen Sie zu?
Mehr Promotion
Der Code funktioniert gut, obwohl es nicht sehr elegant ist, dem Voroader zu sagen, was zu tun ist, nachdem die Gruppe geladen wurde. Möglicherweise möchten Sie Versprechen anstelle von Rückrufen verwenden, insbesondere wenn wir Promise verwendet haben! Ich bin mir nicht sicher, wie ich dieses Problem lösen soll, daher muss ich zugeben, dass ich meinen Freund Valérian Galliat gebeten habe, mir bei diesem Problem zu helfen. Was wir hier verwenden, ist Verzögerungsversprechen . Verspätetes Versprechen ist nicht Teil der nativen Versprechen -API. Daher müssen wir Polyfills hinzufügen; Grundsätzlich ist das verspätete Versprechen ein Versprechen, das später analysiert werden kann. Wenn Sie es auf unseren Code anwenden, ändert sich nur sehr wenig. Erstens ist die .queue(..)
Methode:
<code class="language-javascript">var ImagePreloader = function () { ... }; ImagePreloader.prototype.queue = function () { ... } ImagePreloader.prototype.preloadImage = function () { ... } ImagePreloader.prototype.preload = function () { ... }</code>Analyse in der Methode
.preload(..)
:
<code class="language-javascript">var ImagePreloader = function () { this.items = []; }</code>
Natürlich fügen wir am Ende Daten zur Warteschlange hinzu!
<code class="language-javascript">// 如果没有指定回调,则为空函数 function noop() {} ImagePreloader.prototype.queue = function (array, callback) { this.items.push({ collection: array, // 如果没有回调,我们推送一个no-op(空)函数 callback: callback || noop }); };</code>
Wir sind fertig! Wenn Sie sehen möchten, wie der Code tatsächlich ausgeführt wird, lesen Sie die Demo unten: (Der CODEPEN -Demo -Link sollte hier eingefügt werden, da ich CodePen nicht direkt einbetten kann)
Schlussfolgerung
Okay, Freunde. Mit etwa 70 Zeilen JavaScript -Code haben wir erfolgreich Bilder in verschiedenen Sammlungen asynchron geladen und nach dem Laden der Sammlung einen Code ausgeführt. Von hier aus können wir viele Dinge tun. In meinem Beispiel liegt der Fokus darauf, diese Bilder als Schnellschleifensequenz (GIF -Stil) auszuführen, wenn die Schaltfläche klickt. Deshalb habe ich die Taste während des Ladens deaktiviert und neu aufgelegt, nachdem die Gruppe alle Bilder vorgeladen hat. Da der Browser bereits alle Bilder zwischengespeichert, läuft die erste Schleife sehr reibungslos. Ich hoffe es gefällt dir! Sie können den Code auf GitHub anzeigen oder direkt auf CodePen verwenden. (GitHub -Link und CodePen -Link sollten hier eingefügt werden)
(Der FAQ -Teil sollte hier hinzugefügt werden, was mit dem FAQ -Teil im Eingabetxt übereinstimmt, aber einige Anpassungen und Lackieren wurden im Sprachausdruck vorgenommen.)
Das obige ist der detaillierte Inhalt vonVorladende Bilder parallel zu Versprechungen. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!