Heim  >  Artikel  >  Web-Frontend  >  nodejs arbeitet als nächstes in Express

nodejs arbeitet als nächstes in Express

php中世界最好的语言
php中世界最好的语言Original
2018-04-18 11:20:291943Durchsuche

Dieses Mal werde ich Ihnen zeigen, welche Vorsichtsmaßnahmen für den Express-Betrieb von NodeJS gelten. Das Folgende ist ein praktischer Fall, schauen wir uns das an.

Ich glaube, dass viele Leute nicht viel über Next in Express in NodeJS wissen. Die meisten Leute wissen nicht, was Next tut und unter welchen Umständen es verwendet wird Einführung dazu. Wenn Sie interessiert sind, lassen Sie uns lernen, wie man es benutzt.

In letzter Zeit verwendet das Unternehmen Node, um das Front-End und das Back-End zu trennen. Daher habe ich vor einiger Zeit einen Artikel über Express-Routing geschrieben, aber es scheint so In diesem Artikel fehlt eine wichtige Sache. Der Inhalt ist der nächste von Express, daher werde ich heute separat über den nächsten von Express sprechen.

Als nächstes werde ich es hauptsächlich anhand von drei Punkten erklären:

  • Welche Funktion hat next?

  • Wann sollten wir als nächstes verwenden?

  • Was ist der interne Implementierungsmechanismus von next?

Die Rolle des Nächsten

Wenn wir die Express-Funktion

Middleware definieren, definieren wir als Nächstes die nächste Funktion, die hauptsächlich für die Übergabe der Steuerung an die nächste Middleware verantwortlich ist Wird die Anfrage von der Software nicht beendet und next nicht aufgerufen, wird die Anfrage angehalten und die später definierte Middleware erhält keine Chance zur Ausführung.

Wann sollte „Weiter“ verwendet werden?

Aus der obigen Beschreibung wissen wir bereits, dass die nächste Funktion hauptsächlich dazu dient, sicherzustellen, dass alle registrierten Middleware nacheinander ausgeführt werden. Dann sollten wir die nächste Funktion in der gesamten Middleware aufrufen, aber es gibt einen Sonderfall, wenn wir die Middleware definieren beendet diese Anfrage, daher sollte die nächste Funktion nicht erneut aufgerufen werden, da es sonst zu Problemen kommen kann

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: {}
 });
});
Senden Sie die Anfrage „/a“, das Konsolendruckprotokoll lautet 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)
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 versucht, zu res zu gelangen ​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~~~

Der interne Mechanismus von Next

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);
  }
 }
Das Obige ist der Quellcode von next in Express. Um das Problem einfacher zu erklären, wurde der Code gelöscht. 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 dann die Ebene Der angeforderte Pfad stimmt überein. Wenn die Übereinstimmung erfolgreich ist, wird „layer.handle_request“ ausgeführt und die Middleware-Funktion aufgerufen. Wenn die Übereinstimmung jedoch fehlschlägt, wird die nächste Ebene (Middleware) in einer Schleife ausgeführt.

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, da das von uns angeforderte „/xxx“ nicht mit dem von uns registrierten „/a“ übereinstimmt. leitet die Middleware weiter, sodass die while-Schleife weiterhin ausgeführt wird. Wenn die 404-Middleware erfolgreich abgeglichen wird, wird die 404-Middleware ausgeführt.

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. Was Sie oben sehen, ist die nächste Funktion der 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);
  }
 }

这个next比上边的那个next要简单很多,它负责同一个路由的多个中间件的控制权的传递,并且它会接收一个参数"route",如果调用next(“route”),则会跳过当前路由的其它中间件,直接将控制权交给下一个路由。

最后有必要再说一说next(err),next(err)是如何将控制权传递到错误处理中间件的,从前边的代码我们知道,当调用next(err)是,express内部会调用layer.handle_error,那我们来看看它的源码

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);
 }
};

代码中的fn就是中间件函数,express会对fn的参数个数进行判断,如果参数个数不等于4则认为不是错误处理中间件,则继续调用next(err),这样就会进入到下一个中间件函数,继续进行参数个数判断,如此方式一直到某个中间件函数的参数个数是4,就认为找到了错误处理中间件,然后执行此中间件函数。

相信看了本文案例你已经掌握了方法,更多精彩请关注php中文网其它相关文章!

推荐阅读:

Express Session实现登录验证功能(附代码)

js面向对象深入理解

Das obige ist der detaillierte Inhalt vonnodejs arbeitet als nächstes in Express. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn