Dieser Artikel stellt hauptsächlich das Verständnis von nodejs für die nächste Funktion in Express vor, die einen gewissen Referenzwert hat.
Seit kurzem verwendet das Unternehmen Node, um das Front-End und das Back-End zu trennen Das verwendete Web-Framework ist Express, daher habe ich ein tiefes Verständnis des Express-Frameworks. Ich habe vor einiger Zeit einen Artikel über Express-Routing geschrieben, aber es scheint, dass in diesem Artikel, der der nächste von Express ist, ein sehr wichtiger Inhalt fehlt , also heute Lassen Sie uns separat über den nächsten Express sprechen.
Ich werde Next hauptsächlich anhand von drei Punkten erklären:
Welche Rolle spielt Next?
Wann sollten wir als nächstes verwenden?
Was ist der interne Implementierungsmechanismus von next?
Die Rolle von Next
Wenn wir die Express-Middleware-Funktion definieren, definieren wir den dritten Parameter als next, und dieser next ist unser Der heutige Protagonist, die Next-Funktion, ist hauptsächlich für die Übergabe der Kontrolle an die Next-Middleware verantwortlich. Wenn die aktuelle Middleware die Anfrage nicht beendet und Next nicht aufruft, wird die Anfrage angehalten und die später definierte Middleware wird nicht ausgeführt.
Wann Next verwendet werden soll
Aus der obigen Beschreibung wissen wir bereits, dass die Next-Funktion hauptsächlich dazu dient, sicherzustellen, dass dann alle registrierten Middleware einzeln ausgeführt werden Wir sollten die nächste Funktion in jeder Middleware aufrufen, aber es gibt einen Sonderfall. Wenn die von uns definierte Middleware diese Anforderung beendet, sollte die nächste Funktion nicht erneut aufgerufen werden, da sonst Probleme auftreten können 🎜>
app.get('/a', function(req, res, next) {
res.send('sucess');
next();
});
// catch 404 and forward to error handler
app.use(function(req, res, next) {
console.log(404);
var err = new Error('Not Found');
err.status = 404;
next(err);
});
app.use(function(err, req, res, next) {
res.status(err.status || 500);
res.render('error', {
message: err.message,
error: {}
});
});
Nach dem Login kopieren
sendet die Anfrage „/a“ und die Konsole druckt das Protokoll wie folgt:
404
GET /a 500 6.837 ms - -
Error: Can't set headers after they are sent.
at ServerResponse.OutgoingMessage.setHeader (_http_outgoing.js:345:11)
Nach dem Login kopieren
Warum löst der Code eine Ausnahme aus? Das liegt daran, dass wir die nächste Funktion nach res.send aufgerufen haben. Obwohl unsere Anfrage beendet wurde, wird die nachfolgende 404-Middleware weiterhin ausgeführt und die nachfolgende Middleware versucht, Attributwerte hinzuzufügen auf Header, daher wird die obige Ausnahme ausgelöst.
Nachdem Sie dies gelesen haben, haben Sie möglicherweise eine Frage: Wenn ich die nächste Funktion nach res.send nicht aufrufe, wird die später definierte 404-Middleware nie ausgeführt? Jetzt löschen wir den nächsten Funktionsaufruf nach res.send und senden die Anfrage „/xxx“, wir werden feststellen, dass die 404-Middleware ausgeführt wird, (ㄒoㄒ), steht das nicht im Widerspruch zu dem, was wir zuvor gesagt haben, unsere Anpassung Die Middleware ruft nicht weiter auf, aber die später definierte Middleware wird trotzdem ausgeführt. Warum ist das so? Es scheint, dass wir nur den Quellcode um Hilfe bitten können~~~
Next's interner Mechanismus
function next(err) {
... //此处源码省略
// find next matching layer
var layer;
var match;
var route;
while (match !== true && idx < stack.length) {
layer = stack[idx++];
match = matchLayer(layer, path);
route = layer.route;
if (typeof match !== 'boolean') {
// hold on to layerError
layerError = layerError || match;
}
if (match !== true) {
continue;
}
... //此处源码省略
}
... //此处源码省略
// this should be done for the layer
if (err) {
layer.handle_error(err, req, res, next);
} else {
layer.handle_request(req, res, next);
}
}
Nach dem Login kopieren
The Oben ist der nächste Express-Quellcode, der gelöscht wurde, um die Erklärung des Problems zu erleichtern. Aus dem obigen Quellcode können wir erkennen, dass es in der nächsten Funktion eine While-Schleife gibt. Jede Schleife entfernt eine Ebene aus dem Stapel. Diese Ebene enthält Routing- und Middleware-Informationen, und diese Ebene wird dann zum Abgleichen der angeforderten Ebene verwendet Wenn der Abgleich erfolgreich ist, wird „layer.handle_request“ ausgeführt und die Middleware-Funktion aufgerufen. Wenn die Übereinstimmung jedoch fehlschlägt, wird die nächste Ebene (dh die Middleware) in einer Schleife durchlaufen.
Jetzt können wir das oben angesprochene Problem erklären, warum die nächste Funktion in unserer benutzerdefinierten Middleware nicht aufgerufen wird, die nachfolgende 404-Middleware jedoch trotzdem ausgeführt wird, weil wir „/xxx“ angefordert haben. Die „/a“-Routing-Middleware Wir haben keine Übereinstimmung gefunden, daher wird die while-Schleife weiterhin ausgeführt. Die übereinstimmende 404-Middleware ist erfolgreich, sodass die 404-Middleware ausgeführt wird.
Hinweis: Wenn der Pfadparameter für bei app.use registrierte Middleware leer ist, ist er standardmäßig „/“ und Middleware mit dem Pfad „/“ stimmt standardmäßig mit allen Anforderungen überein.
Auf eines muss besonders hingewiesen werden: Wenn wir Routing-Middleware definieren, ist der dritte Parameter next der Funktion nicht derselbe wie der dritte Parameter next der Funktion, wenn wir Nicht-Routing-Middleware definieren. Routing-Middleware. Was Sie oben sehen, ist die nächste Nicht-Routing-Middleware, und die nächste Funktion der Routing-Middleware ist wie folgt:
function next(err) {
if (err && err === 'route') {
return done();
}
var layer = stack[idx++];
if (!layer) {
return done(err);
}
if (layer.method && layer.method !== method) {
return next(err);
}
if (err) {
layer.handle_error(err, req, res, next);
} else {
layer.handle_request(req, res, next);
}
}
Nach dem Login kopieren
Diese nächste Funktion ist viel einfacher als Die obige ist für die Übergabe der Steuerung mehrerer Middlewares derselben Route verantwortlich und erhält einen Parameter „route“. Wenn next(„route“) aufgerufen wird, werden andere Middlewares der aktuellen Route übersprungen Übergeben Sie die Kontrolle an die nächste Route.
Abschließend muss darüber gesprochen werden, wie next(err) die Kontrolle an die Fehlerbehandlungs-Middleware überträgt. Aus dem vorherigen Code wissen wir, dass beim Aufruf von next(err) die Express-Schicht verwendet wird .handle_error wird intern aufgerufen, also werfen wir einen Blick auf den Quellcode
Layer.prototype.handle_error = function handle_error(error, req, res, next) {
var fn = this.handle;
if (fn.length !== 4) {
// not a standard error handler
return next(error);
}
try {
fn(error, req, res, next);
} catch (err) {
next(err);
}
};
Nach dem Login kopieren
Der fn im Code ist die Middleware-Funktion, und Express bestimmt die Nummer Wenn die Anzahl der Parameter von fn nicht gleich 4 ist, handelt es sich nicht um einen Fehler bei der Middleware. Rufen Sie dann weiter auf (err). Wenn die Anzahl der Parameter der Middleware-Funktion 4 beträgt, wird davon ausgegangen, dass die Fehlerbehandlungs-Middleware gefunden wurde, und dann wird die Middleware-Funktion ausgeführt.
Das obige ist der detaillierte Inhalt vonDetaillierte Erläuterung der Verwendung der nächsten Funktion in Express in NodeJS. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!