Heim >Web-Frontend >js-Tutorial >Datenstrukturen und Algorithmen in JavaScript (2): Queue_Javascript-Kenntnisse
Eine Warteschlange ist eine lineare Liste, die nur Einfügevorgänge an einem Ende und Löschvorgänge am anderen Ende zulässt. Die Warteschlange ist eine First-In-First-Out (FIFO)-Datenstruktur
Queue wird sehr häufig im Programmdesign verwendet, da JavaScript zu jedem Zeitpunkt nur eine Aufgabe ausführen kann und außerdem mit einem asynchronen Mechanismus kombiniert wird
Dann das Problem:1. Wenn der asynchrone Vorgang ausgeführt wird, läuft der synchrone Code noch weiter, dann hängt der synchrone Code von der asynchronen Operation ab und es treten natürlich Fehler auf
2. Mehrere synchronisierte Aufgaben werden zu unterschiedlichen Zeitpunkten aufgerufen
In der jQuery-Animation schreiben wir häufig einen kontinuierlichen Animationscode
$book.animate({ opacity: 0.25, }).animate({ opacity: 0.5 }).animate({ opacity: 1 })
Das intuitive Gefühl, das wir haben, ist: Nachdem die erste Animation beendet ist, beträgt die Deckkraft des Elements 0,25, und dann beginnt die Ausführung der zweiten Animation, und die Deckkraft des Elements beträgt 0,5 und so weiter. Tatsächlich liegt hier jedoch ein wesentliches Problem vor, da die Animation asynchron aufgerufen wird und die Animationsmethode synchron ausgeführt wird. Daher muss hier auch eine Warteschlangenmethode entworfen werden, die speziell für Animationen entwickelt wurde Die Warteschlange ist auch eine spezielle lineare Liste. In JavaScript können wir Arrays direkt verwenden, um ein solches Design zu implementieren. Die Push()-Methode des Arrays kann Elemente am Ende des Arrays hinzufügen und die Shift()-Methode kann diese löschen erstes Element des Arrays.
function Queue() { this.dataStore = []; this.enqueue = enqueue; this.dequeue = dequeue; this.first = first; this.end = end; this.toString = toString; this.empty = empty; } /////////////////////////// // enqueue()方法向队尾添加一个元素: // /////////////////////////// function enqueue(element) { this.dataStore.push(element); } ///////////////////////// // dequeue()方法删除队首的元素: // ///////////////////////// function dequeue() { return this.dataStore.shift(); } ///////////////////////// // 可以使用如下方法读取队首和队尾的元素: // ///////////////////////// function first() { return this.dataStore[0]; } function end() { return this.dataStore[this.dataStore.length - 1]; } ///////////////////////////// // toString()方法显示队列内的所有元素 // ///////////////////////////// function toString() { var retStr = ""; for (var i = 0; i < this.dataStore.length; ++i) { retStr += this.dataStore[i] + "\n"; } return retStr; } //////////////////////// // 需要一个方法判断队列是否为空 // //////////////////////// function empty() { if (this.dataStore.length == 0) { return true; } else { return false; } } var q = new Queue(); q.enqueue("Aaron1"); q.enqueue("Aaron2"); q.enqueue("Aaron3"); console.log("队列头: " + q.first()); //("Aaron1"); console.log("队列尾: " + q.end()); //("Aaron3");
Die Warteschlange verwendet eine lineare Speicherung, daher gibt es einige Nachteile der sequentiellen Speicherung, z. B. das Anstehen, um Tickets zu kaufen. Wenn der erste es kauft, rücken die folgenden natürlich um einen Platz vor, was die gesamte Warteschlange betrifft. Jedes Mitglied muss vorwärts gehen, aber die Warteschlange von JavaScript wird durch ein Array beschrieben, und die unterste Ebene behebt einige Mängel. Natürlich gibt es auch Probleme mit Suchalgorithmen, z. B. Arrays, die zur Implementierung einfach verknüpfter Listenstrukturen usw. verwendet werden können. Wir besprechen hier nur JavaScript-Warteschlangen
Simulieren Sie jQuery und verwenden Sie Warteschlangen, um eine Animation zu implementieren
<div id="div1" style="width:100px;height:50px;background:red;cursor:pointer;color:#fff;text-align:center;line-height:50px;">点击</div> (function($) { window.$ = $; })(function() { var rquickExpr = /^(?:#([\w-]*))$/; function aQuery(selector) { return new aQuery.fn.init(selector); } /** * 动画 * @return {[type]} [description] */ var animation = function() { var self = {}; var Queue = []; //动画队列 var fireing = false //动画锁 var first = true; //通过add接口触发 var getStyle = function(obj, attr) { return obj.currentStyle ? obj.currentStyle[attr] : getComputedStyle(obj, false)[attr]; } var makeAnim = function(element, options, func) { var width = options.width //包装了具体的执行算法 //css3 //setTimeout element.style.webkitTransitionDuration = '2000ms'; element.style.webkitTransform = 'translate3d(' + width + 'px,0,0)'; //监听动画完结 element.addEventListener('webkitTransitionEnd', function() { func() }); } var _fire = function() { //加入动画正在触发 if (!fireing) { var onceRun = Queue.shift(); if (onceRun) { fireing = true; //next onceRun(function() { fireing = false; _fire(); }); } else { fireing = true; } } } return self = { //增加队列 add: function(element, options) { Queue.push(function(func) { makeAnim(element, options, func); }); //如果有一个队列立刻触发动画 if (first && Queue.length) { first = false; self.fire(); } }, //触发 fire: function() { _fire(); } } }(); aQuery.fn = aQuery.prototype = { run: function(options) { animation.add(this.element, options); return this; } } var init = aQuery.fn.init = function(selector) { var match = rquickExpr.exec(selector); var element = document.getElementById(match[1]) this.element = element; return this; } init.prototype = aQuery.fn; return aQuery; }()); //dom var oDiv = document.getElementById('div1'); //调用 oDiv.onclick = function() { $('#div1').run({ 'width': '500' }).run({ 'width': '300' }).run({ 'width': '1000' }); };
Testen