Heim > Artikel > Web-Frontend > Jquery Promise implementiert das Laden von Bildern einzeln_jquery
Promise ist eine der Spezifikationen von CommonJS. Es verfügt über die Methoden „Resolve“, „Reject“, „Done“, „Fail“, „Then“ und andere, die uns helfen können, den Codefluss zu steuern und eine mehrschichtige Verschachtelung von Funktionen zu vermeiden. Heutzutage wird Asynchronität in der Webentwicklung immer wichtiger. Diese Art der nichtlinearen Ausführungsprogrammierung wird es für Entwickler schwierig machen, den Ausführungsprozess des beliebten js besser zu kontrollieren Als jQuery Alle Bibliotheken haben dieses Objekt bereits implementiert, und ES6, das Ende des Jahres veröffentlicht wird, wird Promise auch nativ implementieren.
Im Proxy-Modus der JavaScript-Entwurfsmusterpraxis – Vorladen von Bildern – wird die Funktion zum Vorladen von Bildern mithilfe des Proxy-Modus implementiert.
Jetzt gehen wir noch einen Schritt weiter und vervollständigen eine Funktion, mit der fortlaufende Bilder einzeln geladen werden können.
Funktion:
1. Bilder einzeln laden.
2. Ladefehler, das Bild des Ladefehlers wird nach einer Zeitüberschreitung angezeigt.
In Bezug auf die funktionalen Anforderungen wird es nach Abschluss definitiv zu einer Verarbeitung von Ladestatusereignissen und Rückruffunktionen kommen. Dies führt nicht nur zu Verwirrung im Code, sondern zerstört sogar verschiedene Prinzipien, sodass wir zum Schreiben keine gewöhnlichen Methoden mehr verwenden werden. . Angesichts der Eigenschaften dieser Statusbenachrichtigung ist es besser, die Promise-Architektur für die Verarbeitung zu verwenden. Promise ist im Wesentlichen eine Art Abonnement-Veröffentlichungs-Designmuster. Derzeit wird diese Funktion mithilfe des Promises entwickelt, das mit jquery geliefert wird.
1. Schließen Sie eine Proxy-Erstellungsfunktion zum Laden von Bildern ab, die einen Proxy mit Lade-Timeout-, Fehler-, Erfolgs- und Abbruchüberwachungsfunktionen generieren kann.
function createLoadImgProxy(){ var imgCache = new Image(); var dfd = $.Deferred(); var timeoutTimer; //开始加载超时监控,超时后进行reject操作 function beginTimeoutWatcher(){ timeoutTimer = setTimeout(function(){ dfd.reject('timeout'); }, 10000); } //结束加载超时监控 function endTimeoutWatcher(){ if(!timeoutTimer){ return; } clearTimeout(timeoutTimer); } //加载完成事件处理,加载完成后进行resolve操作 imgCache.onload = function(){ dfd.resolve(this.src); }; //加载终止事件处理,终止后进行reject操作 imgCache.onabort = function(){ dfd.reject("aborted"); }; //加载异常事件处理,异常后进行reject操作 imgCache.onerror = function(){ dfd.reject("error"); }; return function(eleImg, src){ dfd.always(function(){ //加载完成或加载失败都要终止加载超时监控 endTimeoutWatcher(); }).done(function(src){ //加载完成后,往图片元素上设置图片 loadImg(eleImg, src); }).fail(function(msg){ //加载失败后,往图片元素上设置失败图片 loadImg(eleImg, 'loadFailed.jpg'); }); loadImg(eleImg, 'loading.gif'); imgCache.src = src; //开始进行超时加载监控 beginTimeoutWatcher(); return dfd.promise(); }; }
Darunter wird ein verzögertes Objekt auf folgende Weise erstellt
Das verzögerte Objekt löst das Abschlussereignis über die Auflösungsmethode aus und reagiert auf das Abschlussereignis mithilfe der Methode „Done“.
Ereignis abschließen, wenn der Ladevorgang erfolgreich war.
und die Antwortverarbeitung nach Abschluss des Ladevorgangs dienen dazu, das Bild auf das Element festzulegen. Der folgende Code ist eine Zerlegung der oben genannten Kettenschreibmethode.
Das Defferred-Objekt löst über die Reject-Methode ein Ablehnungsereignis aus und reagiert mit der Fail-Methode auf das Ablehnungsereignis, was darauf hinweist, dass der Ladevorgang fehlgeschlagen ist.
Ereignisse ablehnen, wenn Zeitüberschreitung, Beendigung oder Ausnahme beim Laden auftritt.
//开始加载超时监控,超时后进行reject操作 function beginTimeoutWatcher(){ timeoutTimer = setTimeout(function(){ dfd.reject('timeout'); }, 10000); } //加载终止事件处理,终止后进行reject操作 imgCache.onabort = function(){ dfd.reject("aborted"); }; //加载异常事件处理,异常后进行reject操作 imgCache.onerror = function(){ dfd.reject("error"); };
dfd.fail(function(msg){ //加载失败后,往图片元素上设置失败图片 loadImg(eleImg, 'loadFailed.jpg'); });Am Ende der Proxy-Funktion wird das verzögerte Versprechenobjekt zurückgegeben, das zur Überwachung des Abschluss- und Fehlerstatus des Ladevorgangs an den aufrufenden Ort verwendet wird, um das Laden des nächsten Bildes zu erleichtern.
dfd.promise(); zurückgeben
//一张一张的连续加载图片 //参数: // srcs: 图片路径数组 function doLoadImgs(srcs){ var index = 0; (function loadOneByOne(){ //退出条件 if(!(s = srcs[index++])) { return; } var eleImg = createImgElement(); document.getElementById('imgContainer').appendChild(eleImg); //创建一个加载代理函数 var loadImgProxy = createLoadImgProxy(); //在当前图片加载或失败后,递归调用,加载下一张 loadImgProxy(eleImg, s).always(loadOneByOne); })(); }Erstellen Sie eine rekursive Ladefunktion von LoadOneByOne.
Ein Ladeagent wird zunächst intern erstellt. Nachdem der Agent das Bild geladen hat, wird unabhängig von Erfolg oder Misserfolg die Funktion „loadOneByOne“ rekursiv aufgerufen, um das nächste Bild zu laden.
Der Schlüssel liegt im Promise-Objekt, das von der Proxy-Funktion zurückgegeben wird. Verwenden Sie die .always-Methode, um einen rekursiven Aufruf von „loadOneByOne“ durchzuführen, um das nächste Bild zu laden, nachdem der Ladevorgang abgeschlossen ist (Erfolg oder Misserfolg).
至此完成。
采用了promise模式后,callback函数不见了,维护状态的函数和内部变量也不见了,代码更清晰简单,使得代理函数和本地函数之间的一致性得到保护。
完整代码:
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> </head> <body> <button id='btnLoadImg'>加载图片</button> <br> <div id='imgContainer'> </div> <br> <script type='text/javascript' src="./jquery-1.11.3.min.js"></script> <script type='text/javascript'> var imgSrcs = [ 'http://img.wanchezhijia.com/A/2015/3/20/17/11/de63f77c-f74f-413a-951b-5390101a7d74.jpg', 'http://www.newbridgemotorsport.com/files/6413/9945/0406/IMG_3630.jpg', 'http://www.carsceneuk.com/wp-content/uploads/2015/03/88y9989.jpg', 'http://mfiles.sohu.com/20130223/5ff_403b2e7a_7a1f_7f24_66eb_79e3f27d58cf_1.jpg', 'http://img1.imgtn.bdimg.com/it/u=2678963350,1378052193&fm=21&gp=0.jpg' ]; $(document).ready(function(){ $('#btnLoadImg').bind('click', function(){ doLoadImgs(imgSrcs); }); }); //创建img标签 //这里用自执行函数加一个闭包,是为了可以创建多个id不同的img标签。 var createImgElement = (function(){ var index = 0; return function() { var eleImg = document.createElement('img'); eleImg.setAttribute('width', '200'); eleImg.setAttribute('heght', '150'); eleImg.setAttribute('id', 'img' + index++); return eleImg; }; })(); function loadImg(img, src) { img.src = src; } function createLoadImgProxy(){ var imgCache = new Image(); var dfd = $.Deferred(); var timeoutTimer; //开始加载超时监控,超时后进行reject操作 function beginTimeoutWatcher(){ timeoutTimer = setTimeout(function(){ dfd.reject('timeout'); }, 10000); } //结束加载超时监控 function endTimeoutWatcher(){ if(!timeoutTimer){ return; } clearTimeout(timeoutTimer); } //加载完成事件处理,加载完成后进行resolve操作 imgCache.onload = function(){ dfd.resolve(this.src); }; //加载终止事件处理,终止后进行reject操作 imgCache.onabort = function(){ dfd.reject("aborted"); }; //加载异常事件处理,异常后进行reject操作 imgCache.onerror = function(){ dfd.reject("error"); }; return function(eleImg, src){ dfd.always(function(){ // alert('always end'); //加载完成或加载失败都要终止加载超时监控 endTimeoutWatcher(); }).done(function(src){ // alert('done end'); //加载完成后,往图片元素上设置图片 loadImg(eleImg, src); }).fail(function(msg){ // alert('fail end:' + msg); //加载失败后,往图片元素上设置失败图片 loadImg(eleImg, 'loadFailed.jpg'); }); loadImg(eleImg, 'loading.gif'); imgCache.src = src; //开始进行超时加载监控 beginTimeoutWatcher(); return dfd.promise(); }; } //一张一张的连续加载图片 //参数: // srcs: 图片路径数组 function doLoadImgs(srcs){ var index = 0; (function loadOneByOne(){ //退出条件 if(!(s = srcs[index++])) { return; } var eleImg = createImgElement(); document.getElementById('imgContainer').appendChild(eleImg); //创建一个加载代理函数 var loadImgProxy = createLoadImgProxy(); //在当前图片加载或失败后,递归调用,加载下一张 loadImgProxy(eleImg, s).always(loadOneByOne); })(); } </script> </body> </html>