In JavaScript sind verkettete Methodenaufrufe sehr beliebt, und Freunde, die jQuery verwenden, müssen ein tiefes Verständnis dafür haben. Diese Methode wird in „Javascript Design Patterns“ ausführlicher beschrieben. Um Kettenaufrufe von Methoden zu implementieren, müssen Sie nur zulassen, dass die im Prototyp definierten Methoden Verweise auf die Instanzobjekte zurückgeben, die diese Methoden aufrufen Code:
(Funktion() {
Funktion _$(els) {
this.elements = [];
for (var i = 0, len = els.length; i < len; ++i) {
var element = els[i];
if (typeof element == 'string') {
element = document.getElementById(element);
}
this.elements.push(element);
}
};
_$.prototype = {
jeweils: function(fn) {
for ( var i = 0, len = this.elements.length; i < len; ++i ) {
fn.call(this, this.elements[i]);
}
gib dies zurück;
},
setStyle: function(prop, val) {
this.each(function(el) {
el.style[prop] = val;
});
gib dies zurück;
},
show: function() {
var that = this;
this.each(function(el) {
that.setStyle('display', 'block');
});
gib dies zurück;
},
addEvent: function(type, fn) {
var add = function(el) {
if (window.addEventListener) {
el.addEventListener(type, fn, false);
}
sonst if (window.attachEvent) {
el.attachEvent('on'+type, fn);
}
};
this.each(function(el) {
add(el);
});
gib dies zurück;
}
};
window.$ = function() {
return new _$(arguments);
};
})();
Wie Sie sehen, endet jede Methode mit „return this“, wodurch das Objekt der aufrufenden Methode an die nächste Methode in der Kette übergeben wird. Wenn die Daten, die wir verarbeiten möchten, jedoch über eine asynchrone Anforderung abgerufen werden, wie kann dann die Kette der Methodenaufrufe aufrechterhalten werden? Dustin Diaz bietet uns eine Möglichkeit, verkettete Methodenaufrufe sicherzustellen. Er ist auch einer der Autoren des Buches „Javascript Design Patterns“.
Er konstruierte zunächst ein Queue-Objekt, nämlich:
Verwenden Sie es dann als Werkzeug zum Aufbau unserer asynchronen Methodenwarteschlangenkette. Mit diesem Tool ist es einfach, ein jQuery-Plugin zu erstellen, das Inhalte vom Server abruft und an einen Selektor anhängt.
Auf diese Weise können wir den Inhalt asynchron abrufen und unsere Aufrufkette fortsetzen.
$("<div/>")
.fetch('/server/navigation.html')
.addClass('Spalte')
.appendTo('#side');
Schauen Sie sich die Demoseite an, um den Effekt zu sehen.
Was ist zu tun, wenn in einer Warteschlange viele Elemente darauf warten, auf eine serverseitige Antwort reagiert zu werden? Der Autor hat eine solche Methode entwickelt, auf die es sich zu beziehen lohnt:
Auf diese Weise können wir es wie folgt aufrufen:
fetchTweet(url).linkify().filterBadWords().appendTo('#status');
Zu diesem Zeitpunkt wissen wir bereits, wie man die asynchrone Methodenverkettung implementiert, aber einige Fragen, die in einigen Kommentaren am Ende von „ Asynchrone Methodenwarteschlangenverkettung in JavaScript “ aufgeworfen werden, sind es wert, darüber nachzudenken. Das Plug-in $.fn.fetch muss nur den zurückgegebenen Inhalt an das Element anhängen. Ist Queue notwendig? Darüber hinaus kann $.fn.load in jQuery vollständig implementiert werden. Wenn in Queue nur eine Callback-Funktion verwendet wird, kann sie wie folgt geschrieben werden:
(Funktion($) {
$.fn.fetch = function(url) {
var queue = neue Warteschlange;
this.each(function() {
var el = dies;
$.ajax({
URL: URL,
Typ: 'get',
Datentyp: 'json',
Erfolg: Funktion(bzw.) {
$(el).html(resp['text1']);
}
});
});
gib dies zurück;
};
})(jQuery);
Ich frage mich, was Sie denken?
Funktion fetchTweet(url) {
this.queue = neue Warteschlange;
this.tweet = "";
var self = this;
ajax(URL, Funktion(bzw.) {
self.tweet = resp;
self.queue.flush(this);
});
}
fetchTweet.prototype = {
linkify: function() {
this.queue.add(function(self) {
self.tweet = self.tweet.replace(/b@(w{1,20}b/g, '$1');
});
gib dies zurück;
},
filterBadWords: function() {
this.queue.add(function(self) {
self.tweet = self.tweet.replace(/b(fuck|shit|piss)b/g, "");
});
gib dies zurück;
},
appendTo: function(selector) {
this.queue.add(function(self) {
$(self.tweet).appendTo(selector);
});
gib dies zurück;
}
};
(Funktion($) {
$.fn.fetch = function(url) {
var queue = neue Warteschlange;
this.each(function() {
var el = dies;
queue.add(function(resp) {
$(el).html(resp);
});
});
$.ajax({
URL: URL,
Datentyp: 'html',
Erfolg: function(html) {
queue.flush(html);
}
});
gib dies zurück;
};
})(jQuery);
Funktion Queue() {
// Speichern Sie Ihre Rückrufe
this._methods = [];
// Behalten Sie einen Verweis auf Ihre Antwort
this._response = null;
// Alle Warteschlangen beginnen ohne Leerung
this._lushed = false;
}
Queue.prototype = {
// fügt Ihrer Warteschlange Rückrufe hinzu
hinzufügen: function(fn) {
// wenn die Warteschlange geleert wurde, sofort zurückkehren
if (this._lushed) {
fn(this._response);
// andernfalls in die Warteschlange verschieben
} anders {
this._methods.push(fn);
}
},
Flush: Funktion(bzw.) {
// Hinweis: Flush kommt immer nur einmal vor
if (this._lushed) {
zurückkehren;
}
// Speichern Sie Ihre Antwort für nachfolgende Aufrufe nach Flush()
this._response = resp;
// markieren, dass es geleert wurde
this._lushed = true;
// Verschiebe sie raus und rufe sie zurück
while (this._methods[0]) {
this._methods.shift()(resp);
}
}
};