


Eine ausführliche Diskussion über Optimierungstechniken für Schleifenanweisungen in JavaScript_Javascript-Techniken
Schleifen sind einer der wichtigsten Mechanismen in allen Programmiersprachen. Fast jedes Computerprogramm mit praktischer Bedeutung (Sortieren, Abfragen usw.) enthält keine Schleifen. Schleifen sind auch ein sehr problematischer Teil der Programmoptimierung. Wir müssen häufig die Komplexität des Programms ständig optimieren, sind jedoch aufgrund von Schleifen in die Wahl zwischen zeitlicher Komplexität und räumlicher Komplexität verstrickt.
In Javascript gibt es drei Arten von nativen Schleifen: for () {}, while () {} und do {} while (), von denen for () {} am häufigsten verwendet wird.
For ist jedoch die Art von Schleife, die JavaScript-Ingenieure bei der Optimierung von Programmen am leichtesten ignorieren.
Lassen Sie uns zunächst die Grundkenntnisse von for überprüfen.
Die for-Syntax von JavaScript wird von der C-Sprache übernommen. Es gibt zwei Möglichkeiten, die grundlegende Syntax der for-Schleife zu verwenden.
1. Schleifenarray
Grundlegende Syntax der for-Schleife
für ( /* Initialisierung*/2 / * Beurteilungsbedingung */2 /* Schleifenverarbeitung*/ ) {
//... Logikcode
}
Wir verwenden einen Beispielcode, um dies im Detail zu erklären.
var array = [1, 2, 3 , 4, 5];
var sum = 0;
for (var i = 0, len = array.length; i < len; i) {
sum = array[i];
}
console.log('Die Summe der Array-Elemente ist %d.', sum);
//=> Die Summe der Array-Elemente beträgt 15.
In diesem Code definieren und initialisieren wir zunächst ein Array zum Speichern der zu akkumulierenden Elemente und einer Summen-Ganzzahlvariablen. Als nächstes beginnen wir mit der Schleife. Im Initialisierungscode der for-Schleife haben wir außerdem zwei Variablen definiert und initialisiert: i (Zähler) und len (Alias für die Länge des Schleifenarrays). Wenn i kleiner als len ist, wird die Schleifenbedingung erstellt und der Logikcode erstellt wird ausgeführt; jedes Mal, wenn die Logik ausgeführt wird, wird i um 1 erhöht.
Im Schleifenlogikcode fügen wir das aktuelle Schleifenarrayelement zur Summenvariablen hinzu.
Dieser Zyklus wird durch ein Flussdiagramm wie folgt dargestellt:
Anhand dieses Flussdiagramms können wir leicht erkennen, dass der eigentliche Schleifenkörper im Programm nicht nur unseren Logikcode enthält, sondern auch die Ausführungsbeurteilung und Schleifenverarbeitung zur Implementierung der Schleife selbst .
Auf diese Weise sind unsere Optimierungsideen klar und wir können aus vier Aspekten optimieren.
1. Initialisierungscode vor dem Schleifenkörper
2. Ausführungsbeurteilungsbedingungen im Schleifenkörper
3. Logikcode
4. Verarbeitungscode nach dem Logikcode
ps: Es gibt eine wichtige Beziehung zwischen dem ersten und dem zweiten Punkt.
1.1 Initialisierungscode und Ausführungsbeurteilungsbedingungen optimieren
Schauen wir uns zunächst einen Code an, mit dem jeder sehr vertraut ist.
// falsch!
für ( var i = 02 i < list.length2 i) {
//... Logikcode
Lassen Sie uns alles in dieser Schleife auseinandernehmen und einen Blick darauf werfen:
1. Initialisierungscode – Diese Schleife definiert und initialisiert nur eine Zählervariable.
2. Ausführungsbeurteilungsbedingung – wahr, wenn der Zähler kleiner als die Länge der Liste ist.
3. Verarbeitungscode – der Zähler erhöht sich um 1.
Der eigentliche Schleifenkörper enthält nicht nur unseren Logikcode, sondern auch die Ausführungsbeurteilung und den Verarbeitungscode zur Implementierung der Schleife selbst. Mit anderen Worten: Die Beurteilungsbedingung i < list.length muss vor jeder Schleife ausgeführt werden. In JavaScript ist beim Lesen der Eigenschaften oder Methoden eines Objekts eine Abfrage erforderlich.
Du scheinst etwas zu verstehen? Für diese Beurteilungsbedingung gibt es zwei Operationen: 1. Fragen Sie das Längenattribut aus dem Listenarray ab. 2. Vergleichen Sie die Größen von i und list.length.
Angenommen, das Listenarray enthält n Elemente, muss das Programm bei der Ausführungsbeurteilung dieser Schleife 2n Operationen ausführen.
für (var i = 0 , len = list.length; i < i) {
//...
In diesem verbesserten Code haben wir eine Definition hinzugefügt und eine len-Variable im Initialisierungscode initialisiert, bevor der Schleifenkörper ausgeführt wird, die zum Speichern des Werts von list.length (über Variablen, Ausdrücke, Zeiger und Werte) verwendet wird Der Inhalt wird im zweiten Teil besprochen. Auf diese Weise müssen wir die Attribute des Listenarrays bei der Ausführungsbeurteilung im Schleifenkörper nicht erneut abfragen, und die Anzahl der Operationen beträgt die Hälfte der ursprünglichen.
Wir haben die zeitliche Komplexität des Algorithmus in den obigen Schritten verbessert, aber was sollten wir tun, wenn wir die räumliche Komplexität weiter optimieren möchten? Wenn Ihr Logikcode nicht durch die Schleifenreihenfolge eingeschränkt ist, können Sie die folgenden Optimierungsmethoden ausprobieren.
for (var i = list.length - 1; i >= 0; --i) {
//...
}
Dieser Code kehrt die Reihenfolge der Schleife um, startet den i-Zähler ab dem letzten Elementindex (list.length - 1) und führt eine Schleife vorwärts durch. Um die Anzahl der für die Schleife erforderlichen Variablen auf 1 und in der Ausführungsbeurteilung zu reduzieren, wird die Anzahl der Variablenabfragen reduziert und der Zeitaufwand vor der Ausführung des CPU-Befehls verringert.
1.2 Logikcode optimieren
In der Schleife erhalten wir auf natürliche Weise das aktuelle Array-Element der Schleife, um einige Operationen daran auszuführen oder es zu verwenden, was unweigerlich zu mehreren Aufrufen des Elements führt.
var array = [
{ name : 'Will Wen Gunn', Typ: 'hentai' },
{ Name: 'Vill Lin', Typ: 'moegril' }
];
for (var i = array.length - 1; i >= 0; --i) {
console.log('Name: %s', array[i].name);
console.log('Er/Sie ist ein(n) %s', array[i].type);
console.log('rn');
}
/*=>
Name: Vill Lin
Er/Sie ist ein/e Moegril
Name: Will Wen Gunn
Er/Sie ist ein(e) Hentai
*/
In diesem Code muss das Programm die Namens- und Typattribute jedes Array-Elements abfragen. Wenn das Array n Elemente hat, führt das Programm 4n Objektsuchen durch.
1. array[i]
2. array[i].name
3. array[i]
4. array[i].type
Ich glaube, Sie müssen zu diesem Zeitpunkt über eine Lösung nachgedacht haben, die darin besteht, den Wert des aktuellen Array-Elements einer Variablen zuzuweisen und ihn dann im Logikcode zu verwenden.
var array = [
{ name : 'Will Wen Gunn', Typ: 'hentai' },
{ Name: 'Vill Lin', Typ: 'moegril' }
];
var person = null;
for (var i = array.length - 1; i >= 0 && (person = array[i]); --i) {
console.log('Name: %s', person. name);
console.log('Er/Sie ist ein/e %s', person.type);
console.log('rn');
}
person = null;
Das sieht tatsächlich viel schöner aus.
1. array[i] => var person
2. person.name
3. person.type
Es ist ein bisschen wie foreach in emcascript5, aber es gibt einen großen Unterschied zwischen den beiden, deshalb werde ich es hier nicht erklären.
ps: Vielen Dank für die Korrektur. Nach Experimenten haben wir gelernt, dass der in der Schleife erhaltene Wert ein Wert und kein Zeiger sein muss, wenn die Elemente im Array durch direkte Werteübertragung definiert werden. Unabhängig davon, ob Sie Ausdrücke oder Variablen definieren, wird zusätzlicher Speicherplatz benötigt.
1.3 Optimierter Verarbeitungscode
Eigentlich gibt es im Verarbeitungscode im Schleifenkörper nicht viel zu optimieren. Es reicht aus, wenn der i-Zähler um 1 erhöht wird.
ps: Wenn Sie gute Vorschläge oder Methoden haben, geben Sie diese bitte an. :)
2. Schleifenobjekt (Objekt)
In Javascript kann for auch die Eigenschaften und Methoden von Objekten durchlaufen. Es ist zu beachten, dass die for-Schleife weder den Verpackungstyp, zu dem das Objekt gehört, noch die Prototypeigenschaften und -methoden (Prototyp) im Konstruktor durchlaufen kann.
Die Syntax ist einfacher als das Schleifen eines Arrays.
für (/* Initialisierung*/ var-Taste im Objekt) {
//... Logikcode
}
Wir verwenden diese Methode häufig zum Bedienen von Objekten.
var person = {
'name ' : ' Will Wen Gunn',
'Typ' : 'Hentai',
'Fähigkeit' : ['Programmieren', 'Fotografie', 'Sprechen', 'etc']
};
for (var key in person) {
value = person[key];
// Wenn der Wert ein Array ist, konvertieren Sie ihn in einen String
if (value instanceof Array) {
value = value.join(', ');
}
console.log('%s: %s', key, value);
}
/*=>
Name: Will Wen Gunn
Typ: Hentai
Fähigkeit : Programmieren, Fotografieren, Sprechen usw.
*/
Wenn Sie Mongodb jemals verwendet haben, sind Sie mit dem Abfragemechanismus auf jeden Fall vertraut. Da der Abfragemechanismus von Mongodb wie die Seele seiner API ist, hat die flexible Curd-Operationsmethode Mongodb große Popularität und Entwicklungsdynamik eingebracht.
In der Mongo-API-Implementierung von Nanodb verwendet die Abfrageimplementierung häufig Schleifenobjekte.
var myDB = nano.db('myDB ');
var myColl = myDB.collection('myColl');
var _cursor = myColl.find({
type : 'repo',
language : 'JavaScript'
});
_cursor
.sort({
star: 1
})
.toArray(function(err, rows) {
if (err)
return console.error( ähm);
console.log(rows);
});
Was wir optimieren müssen, ist nicht die Schleife selbst, sondern die Optimierung der Objekte, die Sie durchlaufen müssen.
Zum Beispiel speichert die Nanocollection-Klasse in Nanodb, obwohl sie auf der Oberfläche wie ein Array aussieht, alle Elemente oder ein Objekt, verwendet die ID des Elements als Schlüssel und speichert dann die Elemente.
Dies ist jedoch nicht der Fall. Schüler, die bereits Unterstriche verwendet haben, sollten die Methode _.invert kennen. Dies ist eine ziemlich interessante Methode, sie kehrt die Schlüssel und Werte des übergebenen Objekts um.
var person = {
'name ' : ' Will Wen Gunn',
'type' : 'hentai'
};
var _inverted = _.invert(person);
console.log(_inverted);
/*=>
{
'Will Wen Gunn' : 'name',
'hentai' : 'type'
}
*/
Wenn Sie ein Schleifenobjekt verwenden müssen, um den Wert einiger Eigenschaften des Objekts abzufragen, können Sie die folgende Methode ausprobieren.
var person = {
'name ' : ' Will Wen Gunn',
'type' : 'hentai'
};
var name = 'Will Wen Gunn';
var _inverted = _.invert(person);
if (_inverted[name] === 'name') {
console.log('Catched!');
}
//=> Catched!
Es gibt jedoch nicht viel, was für die Objektabfrage optimiert werden kann. Alles muss auf den tatsächlichen Anforderungen basieren. :p
Als nächstes schauen wir uns die anderen beiden Schleifen an, while () {} und {} while (). Ich glaube, dass jeder, der ein Informatikstudium absolviert hat, diese beiden Zyklen kennt. Der einzige Unterschied zwischen ihnen besteht in der logischen Reihenfolge, in der der Schleifenkörper ausgeführt wird.
Die Ausführungssequenz von while () {} ähnelt der von for () {}. Die Ausführungsbeurteilung erfolgt vor dem Logikcode, der Initialisierungs- und Verarbeitungscode wird jedoch weggelassen.
Wenn die Bedingung gegeben ist, wird der Logikcode ausgeführt, bis die Bedingung nicht mehr wahr ist.
var sum = 0;
while (sum < 10) {
sum = sum 1;
}
console.log(sum);
//=> 15
do {} while () setzt die Ausführungsbeurteilung nach dem Logikcode, d. h. „Zuerst schneiden und später abspielen“.
var sum = 0;
do {
sum = sum 1;
} while (sum < 10);
console.log(sum);
//=> 15
while () {} und do {} while () erfordern ebenfalls keinen Zähler, verwenden jedoch bestimmte Bedingungen, um zu bestimmen, ob der Logikcode ausgeführt oder weiterhin ausgeführt werden soll.
3. while () {} und {} while ()
while () {} und do {} while () werden hauptsächlich in der Geschäftslogik verwendet, um kontinuierlich eine Reihe von Vorgängen auszuführen, um einen bestimmten Zweck zu erreichen, z. B. Aufgabenwarteschlangen.
Aber diese beiden Arten von Schleifen sind gefährlich, da sie standardmäßig nur durch Ausführungsbedingungen gesteuert werden. Wenn der Logikcode keinen Einfluss auf die Ausführungsbeurteilung hat, entsteht eine Endlosschleife.
var sum = 02
// Warnung!
while (sum < 10) {
sum = 1 12
}
Ein solcher Code ist gleichbedeutend mit while (true) {}. Bevor Sie ihn verwenden, müssen Sie daher die Ausführungsbedingungen und die Auswirkungen auf die Ausführungsbedingungen klären.
4. Nutzen Sie Schleifenkontrollanweisungen sinnvoll
Ich glaube, dass alle JavaScript-Ingenieure die Break-Anweisung verwendet haben, die Continue-Anweisung jedoch relativ selten verwendet wird. Tatsächlich ist continue in vielen hervorragenden JavaScript-Open-Source-Projekten zu finden.
Um die Funktion der continue-Anweisung besser zu verstehen, schauen wir uns zunächst einen Beispielcode an
// Node.js Broadcast Server
var net = require('net');
var util = require('util');
var BroadcastServer = net.createServer();
// Client Store
broadcastServer.clients = [];
// Clients Broadcast Method
net.Socket.prototype.broadcast = function(msg) {
var client = BroadcastServer.clients;
// Holen Sie sich den Client, der die Übertragung in der Sammlung Standard veröffentlicht
var index = client.indexOf(this);
for (var i = client.length - 1; i >= 0; --i) {
if (i === index) {
// Wenn es der Client ist, der das veröffentlicht Broadcast, dann die aktuelle Schleife beenden
weitermachen;
}
currClient = client[i];
if (!currClient.destroyed) {
currClient.write(
util.format(
) 'r[Echo Client %s:%d] %snInput: ',
currClient. remoteAddress , currClient.remotePort, msg)
);
}
}
};
// Ein neuer Client ist verbunden
broadcastServer.on('connection', function(client) {
BroadcastServer.clients.push(client);
// Willkommen
client.write('[Broadcast Server] Welcome!nInput:');
client.broadcast(client, 'Joined!');
// Nachrichtenhandle
client.on('data', function(msg) {
client.broadcast(msg);
client.write('rInput:');
} );
// Handle trennen
client.on('end', function() {
client.broadcast('Left!');
})
});
// Bind
broadcastServer.listen(8080, function() {
console.log('Broadcast Serverbound.');
});
Dieser Code implementiert einen Broadcast-Server basierend auf dem Net-Modul von node.js. In der Broadcast-Methode verwenden wir die continue-Anweisung, um Informationen an alle hergestellten Verbindungen mit Ausnahme des Clients zu senden, der den Broadcast-Client veröffentlicht.
Der Inhalt des Codes ist recht einfach. Wenn ein Client eine Übertragung an andere Clients veröffentlichen muss, wird die Broadcast-Methode des Client-Objekts aufgerufen. Bei der Broadcast-Methode ruft das Programm zuerst den Cache ab des aktuellen Clients in der Client-Socket-Sammlung und veröffentlichen Sie dann alle Client-Sockets in einer Schleife. Wenn der Schleifenzähler den zuvor erhaltenen Positionsindex erreicht, wird der Logikcode im aktuellen Schleifenkörper übersprungen und die nächste Schleife fortgesetzt .
Ich glaube, dass Ingenieure, die C/C-Sprache studiert haben, von verschiedenen Seiten diesen Rat erhalten werden: „Verwenden Sie keine Goto-Anweisungen.“
Diese „berüchtigte“ goto-Anweisung ist eigentlich ein Codefluss-Controller. Die Details der goto-Anweisung werden hier nicht im Detail erläutert. JavaScript verfügt jedoch nicht über eine offensichtliche goto-Anweisung, aber anhand der break-Anweisung und der continue-Anweisung ist es nicht schwierig, den Schatten von goto in JavaScript zu finden.
Das liegt daran, dass die break-Anweisung und die continue-Anweisung das Akzeptieren eines definierten Labelnamens für den Codesprung ermöglichen.
Werfen wir einen Blick auf den von mdn bereitgestellten Beispielcode.
var i, j;
loop1:
for (i = 0; i < 3; i ) { //Die erste for-Anweisung trägt die Bezeichnung „loop1“
loop2:
for (j = 0; j < 3; j ) { //Die zweite for-Anweisung trägt die Bezeichnung „loop2“
if (i == 1 && j == 1) {
continue loop1;
console.log ("i = " i ", j = " j);
}
}
}
// "i = 0, j = 0"
// "i = 0, j = 1"
// "i = 0, j = 2"
// "i = 1, j = 0"
// "i = 2, j = 0"
// "i = 2, j = 1"
// "i = 2, j = 2"
// Beachten Sie, dass sowohl „i = 1, j = 1" als auch „i = 1, j = 2" übersprungen wird
Die erste Schleife befindet sich in der Beschriftung von Schleife1. Dies bedeutet, dass im nachfolgenden Programm die äußerste Schleife herausgesprungen wird, wenn die Beschriftung Schleife1 in der Continue-Anweisung oder der Break-Anweisung ausgewählt wird.
Die Schleife der zweiten Ebene befindet sich in der Beschriftung von Schleife2 in der Schleife der obersten Ebene. Wenn die Beschriftung Schleife2 in der Continue-Anweisung oder Break-Anweisung ausgewählt wird, kehrt sie zum Schleifenkörper der Schleife der obersten Ebene zurück.
5. Erweiterte Schleife
5.1 Schleife abrollen
Schauen wir uns zunächst zwei Codeteile an. Erraten Sie, welcher Code die bessere Leistung bietet.
// Setup
var array = [
["DATA", "DATA", "DATA", "DATA", "DATA", "DATA", "DATA", "DATA ", "DATA", "DATA", "DATA", "DATA"],
["DATA", "DATA", "DATA", "DATA", "DATA", "DATA", "DATA" , „DATA“, „DATA“, „DATA“, „DATA“, „DATA“],
[„DATA“, „DATA“, „DATA“, „DATA“, „DATA“, „DATA“, „DATA“, „DATA“, „DATA“, „DATA“, „DATA“, „DATA“],
[„DATA“, „DATA“, „DATA“, „DATA“, „DATA“, „ DATA“, „DATA“, „DATA“, „DATA“, „DATA“, „DATA“, „DATA“],
[„DATA“, „DATA“, „DATA“, „DATA“, „DATA ", "DATA", "DATA", "DATA", "DATA", "DATA", "DATA", "DATA"],
["DATA", "DATA", "DATA", "DATA" , „DATA“, „DATA“, „DATA“, „DATA“, „DATA“, „DATA“, „DATA“, „DATA“],
[„DATA“, „DATA“, „DATA“, „DATA“, „DATA“, „DATA“, „DATA“, „DATA“, „DATA“, „DATA“, „DATA“, „DATA“],
[„DATA“, „DATA“, „ DATA“, „DATA“, „DATA“, „DATA“, „DATA“, „DATA“, „DATA“, „DATA“, „DATA“, „DATA“, „DATA“]
];
Funktionsprozess( item) {
// Mach etwas mit item
}
// Fall 1
for (var i = array.length - 1; i >= 0; i--) {
for (var j = array[i].length - 1; j >= 0; i--) {
process(array[i][j]);
}
}
// Fall 2
for (var i = array.length - 1; i >= 0; i = i - 4) {
for (var j = array[i].length - 1 ; j >= 0; j = j - 6) {
Process(array[i][j]);
Process(array[i][j - 1]);
Process(array [i][j - 2]);
Process(array[i][j - 3]);
Process(array[i][j - 4]);
Process(array[i ][j - 5]);
}
for (var j = array[i - 1].length - 1; j >= 0; j = j - 6) {
process(array [i][j]);
Process(array[i][j - 1]);
Process(array[i][j - 2]);
Process(array[i][ j - 3]);
Process(array[i][j - 4]);
Process(array[i][j - 5]);
}
for (var j = array[i - 2].length - 1; j >= 0; j = j - 6) {
Process(array[i][j]);
Process(array[i][j - 1]);
Process(array[i][j - 2]);
Process(array[i][j - 3]);
Process(array[i][j - 4] );
Process(array[i][j - 5]);
}
for (var j = array[i - 3].length - 1; j >= 0; j = j - 6) {
Process(array[i][j]);
Process(array[i][j - 1]);
Process(array[i][j - 2]);
Process(array[i][j - 3]);
Process(array[i][j - 4]);
Process(array[i][j - 5]);
}
}
我需要对array中的所有子数组的元素进行历遍,有两种方案,一种是我们平常所使用的方法, 另一种是把循环任务展开往常的都要快.
这里我们来看看一种更给力的解决方案。 环节中需要对大数据集进行迭代处理,而这个数据集从开始迭代起,数据量不会再改变, 那麼可以考虑採用一种名为 duff 装置的技术.这项技术是以其的创造者 tom duff 的名字来命名的, 这项技术最先实现於Beschreibung: Jeff Greenberg und Andrew B . König 修改并提出了一种更为高效的版本.
//Credit: Beschleunigen Sie Ihre Website (New Riders, 2003)
var iterations = Math.floor(values.length / 8);
var leftover = Values.length % 8;
var i = 0;
if (leftover > 0) {
do {
process(values[i ]);
} while (--leftover > 0);
}
do {
Process(values[i ]);
Process(values[i ]);
Process(values[i ]);
Process(values[i ]);
Process(values [i ]);
Process(values[i ]);
Process(values[i ]);
Process(values[i ]);
} while (--iterations > 0 );
这种技术的工作原理是通过计算values的长度除以 8 以得到需要迭代的次数,并以math.floor()函数来保证结果为整数, 然后再计算不能被 8 整除时的餘数并对这些元素单独进行处理,其餘则 8 次为单次展开次数来进行迭代.
我将这种装置再加以封装,可以得到一种带有异步味道的 api
function duff(array, mapper) {
var n = Math.floor(array.length / 8);
var l = array.length % 8;
var i = 0;
if (l > 0) {
do {
mapper(array[i ]);
} while (--i > 0);
}
do {
Mapper(array[i]);
Mapper(array[i]);
Mapper(array[i]);
Mapper(array[i] );
Mapper(array[i]);
Mapper(array[i]);
Mapper(array[i]);
Mapper(array[i]);
} while (--n > 0);
}
duff([...], function(item) {
//...
});
Hier finden Sie eine Reihe von Leistungstests und Ergebnissen für die oben genannten drei iterativen Lösungen. http://jsperf.com/spreaded-loop
5.2 Nicht-native Schleife
In jeder Programmiersprache können Schleifen nicht nur durch die von der Sprache bereitgestellten nativen Schleifenanweisungen, sondern auch indirekt durch andere Methoden implementiert werden.
Lassen Sie uns zunächst einige Inhalte der Oberstufenmathematik durchgehen – die allgemeine Formel einer Folge.
bacause
a[1] = 1
a[n] = 2 * a[n - 1] 1
also
a[n] 1 = 2 * a[n - 1] 2 [n - 1] 1) = 2
dann
a[n] 1 = 2 * 2 * ... * 2 * 2
a[n] 1 = 2^n
a[n] = 2^n - 1
final
Rekursion ist eine sehr wichtige Anwendungsmethode in der Mathematik und Informatik. Sie bedeutet, dass eine Funktion sich selbst aufruft, wenn sie verwendet wird.
In der Node.js-Community wird Rekursion verwendet, um eine sehr wichtige Technologie zu implementieren: Middleware-Technologie. Dies ist ein Teil des Middleware-Implementierungscodes in einer neuen Version von webjs, der noch nicht veröffentlicht wurde.
/**
* Middleware-Ausführungsmethode
* @param {String} URL Aktuelle Anfrage-URL
* @param {Object} fordert das Anfrageobjekt an
* @param {Object} res das Antwortobjekt
* @param {Function} out Complete Callback
* @return {Function} den Server
*/
server.runMiddlewares = function(url, req, res, out) {
var index = -1;
var middlewares = this._usingMiddlewares;
// die nächste Middleware ausführen, falls vorhanden
function next(err) {
index ;
// aktuelle Middleware
var curr = middlewares[index];
if (curr) {
var check = new RegExp(curr.route);
// Überprüfen Sie die Route
if (check.test(url)) {
try {
function later() {
debug('Eine Middleware sagt, dass es später sein muss % s', url);
// Die Abhängigkeiten funktionieren derzeit nicht
if (middlewares.indexOf(curr) !== middlewares.length - 1) {
. _later(curr);
Index --;
next();
} else {
debug('Eine Middleware-Abhängigkeit ist falsch');
// Diese Middleware kann nicht ausgeführt werden
out();
}
}
// Middleware ausführen
if (utils.isFunc(curr.handler)) {
// Normale Middleware-Funktion
curr.handler(req, res, next, later);
} else if (utils.isObject(curr.handler) && utils.isFunc(curr.handler.emit)) {
// Serverobjekt
curr.handler.emit('request', req, res, next, later);
} sonst {
// Mit der Middleware stimmt etwas nicht
next();
} } sonst {
// Zum nächsten Schritt der Pipeline
out();
}
}
// wenn die Middleware von anderen Middlewares abhängt,
// kann sie später ausgeführt werden
function _later(curr) {
var i = middlewares.indexOf(curr);
var _tmp1 = middlewares.slice(0, i);
_tmp1.push(middlewares[i 1], curr);
[].push. apply(_tmp1, _tmp2);
middlewares = _tmp1;
}
// erste Middleware
next();
gib dies zurück;
};
虽然这段代码看上去狠复杂,不过如果我们对其精简之后,就清晰许多了.
代码如下:
server.runMiddlewares = function(url, req, res, out) {
var index = -1;
var middlewares = this._usingMiddlewares;
// die nächste Middleware ausführen, falls vorhanden
function next(err) {
index ;
// aktuelle Middleware
var curr = middlewares[index];
if (curr) {
var check = new RegExp(curr.route);
// Route prüfen
if (check.test(url)) {
// aktuelle Middleware ausführen
curr.handler(req, res, next);
} else {
next();
}
} else {
// Zum nächsten Schritt der Pipeline
out();
}
}
// erste Middleware
next();
gib dies zurück;
};
Der Grund, warum Rekursion bei der Implementierung von Middleware-Systemen verwendet werden kann, liegt darin, dass Rekursion die am besten geeignete Programmfluss-Antwortmethode für asynchrone E/A in node.js ist.
In diesem Middleware-Implementierungscode ist this._usingmiddlewares das Schleifenarray, die Funktion next() ist der Schleifenkörper, check.test(url) ist die Ausführungsbeurteilungsbedingung und der Schleifenverarbeitungscode ist die Vorderseite des Schleifenkörpers . Der Indexzähler wird um 1 erhöht und die nächste Funktion selbst wird rekursiv aufgerufen.

Heiße KI -Werkzeuge

Undresser.AI Undress
KI-gestützte App zum Erstellen realistischer Aktfotos

AI Clothes Remover
Online-KI-Tool zum Entfernen von Kleidung aus Fotos.

Undress AI Tool
Ausziehbilder kostenlos

Clothoff.io
KI-Kleiderentferner

AI Hentai Generator
Erstellen Sie kostenlos Ai Hentai.

Heißer Artikel

Heiße Werkzeuge

Notepad++7.3.1
Einfach zu bedienender und kostenloser Code-Editor

SublimeText3 chinesische Version
Chinesische Version, sehr einfach zu bedienen

Senden Sie Studio 13.0.1
Leistungsstarke integrierte PHP-Entwicklungsumgebung

Dreamweaver CS6
Visuelle Webentwicklungstools

SublimeText3 Mac-Version
Codebearbeitungssoftware auf Gottesniveau (SublimeText3)

Heiße Themen

So implementieren Sie mit WebSocket und JavaScript ein Online-Spracherkennungssystem. Einführung: Mit der kontinuierlichen Weiterentwicklung der Technologie ist die Spracherkennungstechnologie zu einem wichtigen Bestandteil des Bereichs der künstlichen Intelligenz geworden. Das auf WebSocket und JavaScript basierende Online-Spracherkennungssystem zeichnet sich durch geringe Latenz, Echtzeit und plattformübergreifende Eigenschaften aus und hat sich zu einer weit verbreiteten Lösung entwickelt. In diesem Artikel wird erläutert, wie Sie mit WebSocket und JavaScript ein Online-Spracherkennungssystem implementieren.

WebSocket und JavaScript: Schlüsseltechnologien zur Realisierung von Echtzeit-Überwachungssystemen Einführung: Mit der rasanten Entwicklung der Internet-Technologie wurden Echtzeit-Überwachungssysteme in verschiedenen Bereichen weit verbreitet eingesetzt. Eine der Schlüsseltechnologien zur Erzielung einer Echtzeitüberwachung ist die Kombination von WebSocket und JavaScript. In diesem Artikel wird die Anwendung von WebSocket und JavaScript in Echtzeitüberwachungssystemen vorgestellt, Codebeispiele gegeben und deren Implementierungsprinzipien ausführlich erläutert. 1. WebSocket-Technologie

So implementieren Sie ein Online-Reservierungssystem mit WebSocket und JavaScript. Im heutigen digitalen Zeitalter müssen immer mehr Unternehmen und Dienste Online-Reservierungsfunktionen bereitstellen. Es ist von entscheidender Bedeutung, ein effizientes Online-Reservierungssystem in Echtzeit zu implementieren. In diesem Artikel wird erläutert, wie Sie mit WebSocket und JavaScript ein Online-Reservierungssystem implementieren, und es werden spezifische Codebeispiele bereitgestellt. 1. Was ist WebSocket? WebSocket ist eine Vollduplex-Methode für eine einzelne TCP-Verbindung.

Einführung in die Verwendung von JavaScript und WebSocket zur Implementierung eines Online-Bestellsystems in Echtzeit: Mit der Popularität des Internets und dem Fortschritt der Technologie haben immer mehr Restaurants damit begonnen, Online-Bestelldienste anzubieten. Um ein Echtzeit-Online-Bestellsystem zu implementieren, können wir JavaScript und WebSocket-Technologie verwenden. WebSocket ist ein Vollduplex-Kommunikationsprotokoll, das auf dem TCP-Protokoll basiert und eine bidirektionale Kommunikation zwischen Client und Server in Echtzeit realisieren kann. Im Echtzeit-Online-Bestellsystem, wenn der Benutzer Gerichte auswählt und eine Bestellung aufgibt

JavaScript und WebSocket: Aufbau eines effizienten Echtzeit-Wettervorhersagesystems Einführung: Heutzutage ist die Genauigkeit von Wettervorhersagen für das tägliche Leben und die Entscheidungsfindung von großer Bedeutung. Mit der Weiterentwicklung der Technologie können wir genauere und zuverlässigere Wettervorhersagen liefern, indem wir Wetterdaten in Echtzeit erhalten. In diesem Artikel erfahren Sie, wie Sie mit JavaScript und WebSocket-Technologie ein effizientes Echtzeit-Wettervorhersagesystem aufbauen. In diesem Artikel wird der Implementierungsprozess anhand spezifischer Codebeispiele demonstriert. Wir

JavaScript-Tutorial: So erhalten Sie HTTP-Statuscode. Es sind spezifische Codebeispiele erforderlich. Vorwort: Bei der Webentwicklung ist häufig die Dateninteraktion mit dem Server erforderlich. Bei der Kommunikation mit dem Server müssen wir häufig den zurückgegebenen HTTP-Statuscode abrufen, um festzustellen, ob der Vorgang erfolgreich ist, und die entsprechende Verarbeitung basierend auf verschiedenen Statuscodes durchführen. In diesem Artikel erfahren Sie, wie Sie mit JavaScript HTTP-Statuscodes abrufen und einige praktische Codebeispiele bereitstellen. Verwenden von XMLHttpRequest

Verwendung: In JavaScript wird die Methode insertBefore() verwendet, um einen neuen Knoten in den DOM-Baum einzufügen. Diese Methode erfordert zwei Parameter: den neuen Knoten, der eingefügt werden soll, und den Referenzknoten (d. h. den Knoten, an dem der neue Knoten eingefügt wird).

Einführung in die Methode zum Abrufen des HTTP-Statuscodes in JavaScript: Bei der Front-End-Entwicklung müssen wir uns häufig mit der Interaktion mit der Back-End-Schnittstelle befassen, und der HTTP-Statuscode ist ein sehr wichtiger Teil davon. Das Verstehen und Abrufen von HTTP-Statuscodes hilft uns, die von der Schnittstelle zurückgegebenen Daten besser zu verarbeiten. In diesem Artikel wird erläutert, wie Sie mithilfe von JavaScript HTTP-Statuscodes erhalten, und es werden spezifische Codebeispiele bereitgestellt. 1. Was ist ein HTTP-Statuscode? HTTP-Statuscode bedeutet, dass der Dienst den Dienst anfordert, wenn er eine Anfrage an den Server initiiert
