Heim  >  Artikel  >  Web-Frontend  >  Verstehen Sie die Prinzipien der Knoten-Middleware von JavaScript in einfachen Worten

Verstehen Sie die Prinzipien der Knoten-Middleware von JavaScript in einfachen Worten

coldplay.xixi
coldplay.xixinach vorne
2020-11-04 17:35:322145Durchsuche

In der heutigen Javascript-Kolumne wird das Prinzip der Node-Middleware vorgestellt.

Verstehen Sie die Prinzipien der Knoten-Middleware von JavaScript in einfachen Worten

Verwandte kostenlose Lernempfehlungen: Javascript (Video)

Vorwort

Middleware ist eine Art Software zwischen Anwendungssystemen und Systemsoftware. Sie verwendet Systemsoftware. Die grundlegenden Dienste ( Die bereitgestellten Funktionen verbinden verschiedene Teile des Anwendungssystems oder verschiedene Anwendungen im Netzwerk und können den Zweck der gemeinsamen Nutzung von Ressourcen und Funktionen erreichen.

In NodeJS bezieht sich Middleware hauptsächlich auf die Methode zum Kapseln von http-Anfragedetails. Wir alle wissen, dass mit http-Anfragen oft viele Aktionen verbunden sind, wie folgt:

  • IP-Filterung
  • Übergabe von Abfragezeichenfolgen
  • Anfragetextanalyse
  • Cookie-Informationsverarbeitung
  • Berechtigungsüberprüfung
  • Protokollierung
  • Sitzungsverwaltung Middleware (Sitzung)
  • Gzip-Komprimierungs-Middleware (z. B. Komprimierung)
  • Fehlerbehandlung

Natürlich gibt es viele benutzerdefinierte Verarbeitungsaktionen. Für Web-Anwendungen möchten wir nicht alle Details der Verarbeitungsarbeit kennen, hoffen aber Um sich auf die Geschäftsentwicklung zu konzentrieren und die Entwicklungseffizienz zu verbessern, wird die „Node-Middleware“ eingeführt, um diese grundlegenden Details der Logikverarbeitung zu vereinfachen und zu kapseln. Knoten-Middleware Es. Wie in der Abbildung unten gezeigt:

Die gängigen NodeJS-Frameworks, die wir derzeit sehen, wie

connect, koa, express,

egg

, nest usw., sind alle untrennbar mit dem Designkonzept verbunden Um allen einen tieferen Einblick in die Welt von NodeJS zu geben, werden wir die Implementierungsprinzipien von Middleware vergleichen. TextNachdem wir das Konzept der Node-Middleware verstanden haben, werden wir die Middleware schließlich manuell implementieren. Wir werden einfach die Implementierungsideen von Middleware in Koa analysieren. Die Gliederung des Artikels lautet wie folgt: Knoten-Middleware-Kernprinzip-Implementierung

Koa-Middle-Key-Implementierungsmethode

Verwenden Sie den Koa-Middleware-Mechanismus, um Ihre eigene Koa-Middleware zu implementieren

    Knoten-Middleware-Implementierung der Kernprinzipien
  • Aus der obigen Einführung können wir ersehen, dass Middleware die Verarbeitungslogik vom Anfang der HTTP-Anfrage bis zum Ende der Antwort ist. Sie muss normalerweise die Anfrage und Antwort verarbeiten Bei der Implementierung des Knoten-Middleware-Modus müssen wir Folgendes berücksichtigen: In Bezug auf die Koexistenz mehrerer Middlewares müssen wir darüber nachdenken, wie die Ausführung mehrerer Middlewares automatisiert werden kann. Andernfalls wird im Prozess von der Anforderung bis zur Antwort nur die anfängliche Middleware ausgeführt Die Grundform der Middleware lautet wie folgt:
  • const middleware = (req, res, next) => {  // 请求处理逻辑
      next()
    }复制代码
  • Connect Schreiben wir zunächst einen einfachen Fall, um zu sehen, wie Middleware implementiert wird
  • // 定义几个中间间函数const m1 = (req, res, next) => {  console.log('m1 run')
      next()
    }const m2 = (req, res, next) => {  console.log('m2 run')
      next()
    }const m3 = (req, res, next) => {  console.log('m3 run')
      next()
    }// 中间件集合const middlewares = [m1, m2, m3]function useApp (req, res) {  const next = () => {    // 获取第一个中间件
        const middleware = middlewares.shift()    if (middleware) {
          middleware(req, res, next)
        }
      }
      next()
    }// 第一次请求流进入useApp()复制代码
  • Aus dem obigen Code ist es nicht schwierig, die Rolle von
next

zu finden, dem Schlüsselparameter um die Middleware-Kette automatisch aufzurufen:

m1 run
m2 run
m3 run复制代码

Das Obige hat den Ausführungsmodus der Basis-Middleware implementiert, aber wir müssen auch das Problem der Asynchronität berücksichtigen. Wenn die Middleware auch auf die Unterstützung von Drittanbietern angewiesen ist. Partymodule oder APIs wie Verifizierung, Identifizierung und andere Dienste müssen wir nur durch Ausführen von next im Rückruf der asynchronen Middleware gewährleisten, um die normale Aufrufausführungssequenz zu gewährleisten, wie im folgenden Code gezeigt:

const m2 = (req, res, next) => {
  fetch('/xxxxx').then(res => {
	next()
  })
}复制代码

Es ​​gibt auch a Middleware-Szenarien wie Protokollierungs-Middleware und Anforderungsüberwachungs-Middleware, die vor der Geschäftsverarbeitung verarbeitet werden. Zu diesem Zeitpunkt müssen wir in der Lage sein, eine sekundäre Verarbeitung für die

nächste

-Funktion durchzuführen Wickeln Sie den Rückgabewert von next in promise ein, damit er nach Abschluss der Geschäftsverarbeitung über

then

aufgerufen werden kann. Fahren Sie mit der Verarbeitung der Middleware-Logik fort, wie unten gezeigt:

function useApp (req, res) {  const next = () => {    const middleware = middlewares.shift()    if (middleware) {      // 将返回值包装为Promise对象
      return Promise.resolve(middleware(req, res, next))
    }else {      return Promise.resolve("end")
    }
  }
  next()
}复制代码

Zu diesem Zeitpunkt können wir es aufrufen auf folgende Weise:

const m1 = (req, res, next) => {  console.log('m1 start')  return next().then(() => {    console.log('m1 end')
  })
}复制代码
Oben haben wir ein grundlegendes Middleware-Entwurfsmuster implementiert. Natürlich können wir es auch mit async and waiting implementieren. Die Schreibmethode wird eleganter und einfacher sein. Hier ist ein einfaches Beispiel des Autors:
const m1 = async (req, res, next) => {    // something...
    let result = await next();
  }  
  const m2 = async (req, res, next) => {    // something...
    let result = await next();
  }  const m3 = async (req, res, next) => {    // something...
    let result = await next();    return result;
  }const middlewares = [m1, m2, m3];function useApp (req, res) {    const next = () => {      const middleware = middlewares.shift()      if (middleware) {        return Promise.resolve(middleware(req, res, next))
      }else {        return Promise.resolve("end")
      }
    }
    next()
  }// 启动中间件useApp()复制代码
Im koa2-Framework wird die Middleware auch implementiert, indem der Rückgabewert der next()-Methode in ein Promise-Objekt gekapselt wird, wodurch der von ihr vorgeschlagene Zwiebelring realisiert wird. Das Modell ist wie in der folgenden Abbildung dargestellt:

Koa-Middleware-Implementierungsmethode

Das Middleware-Implementierungsprinzip des Koa2-Frameworks ist meiner Meinung nach sehr elegant. Hier ist die Kernidee:

function compose (middleware) {  // 提前判断中间件类型,防止后续错误
  if (!Array.isArray(middleware)) throw new TypeError('Middleware stack must be an array!')  for (const fn of middleware) {    // 中间件必须为函数类型
    if (typeof fn !== 'function') throw new TypeError('Middleware must be composed of functions!')
  }  return function (context, next) {    // 采用闭包将索引缓存,来实现调用计数
    let index = -1
    return dispatch(0)    function dispatch (i) {      // 防止next()方法重复调用
      if (i <= index) return Promise.reject(new Error(&#39;next() called multiple times&#39;))
      index = i      let fn = middleware[i]      if (i === middleware.length) fn = next      if (!fn) return Promise.resolve()      try {        // 包装next()返回值为Promise对象
        return Promise.resolve(fn(context, dispatch.bind(null, i + 1)));
      } catch (err) {        // 异常处理
        return Promise.reject(err)
      }
    }
  }
}复制代码

利用koa中间件机制实现一个自己的koa中间件

学习了中间件的设计机制和原理, 我们是不是想马上写一个中间件呢? 笔者这里给大家举一个例子. 在H5-Dooring项目的服务端代码中, 我们需要对用户登录权限进行分发, 此时我们提供统一个中间件来处理, 如下代码所示:

// 模拟数据库操作const token = db.user();// router或者koa的中间件一定要用await处理next,否则将不能正常响应数据export default async (ctx, next) => {  const t = ctx.request.header.authorization  let uid = ctx.request.header['x-requested-with']  let uidArr = uid.split(',')  if(uidArr.length > 1) {
      uid = uidArr.pop().trim()
  }    if(token[uid] && token[uid][1] === t) {        await next()
    }else {
        ctx.status = 403;
        ctx.body = {            state: 403,            msg: '你没有权限操作'
        }
    }  
}复制代码

以上代码即实现用户登录态处理, 如果用户在没有登录的情况下防问任何需要登录的接口, 都将返回权限不足或则在请求库中让其重定向到登录页面.

所以, 今天你又博学了吗?

Das obige ist der detaillierte Inhalt vonVerstehen Sie die Prinzipien der Knoten-Middleware von JavaScript in einfachen Worten. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:juejin.im. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen