ホームページ > ウェブフロントエンド > フロントエンドQ&A > Nodejsにおけるミドルウェアとは何ですか

Nodejsにおけるミドルウェアとは何ですか

青灯夜游
リリース: 2021-10-29 15:52:07
オリジナル
3163 人が閲覧しました

nodejsにおいてミドルウェアとは主にHTTPリクエスト全体の詳細な処理をカプセル化したメソッドを指し、HTTPリクエストの開始からレスポンスの終了までの処理メソッドを指します。ミドルウェアの動作は、特定のビジネス処理に入る前にフィルターに処理させるという Java のフィルターの動作原理に似ています。

Nodejsにおけるミドルウェアとは何ですか

このチュートリアルの動作環境: Windows7 システム、nodejs バージョン 12.19.0、Dell G3 コンピューター。

ミドルウェアの概念

NodeJS では、ミドルウェアとは主に、すべての Http リクエストの詳細をカプセル化するメソッドを指します。 HTTP リクエストには通常、ロギング、IP フィルタリング、クエリ文字列、リクエスト本文の解析、Cookie 処理、権限の検証、パラメータの検証、例外処理などの多くの作業が含まれますが、Web アプリケーションの場合、これらの作業は不要です。開発効率の向上という目的を達成するために、開発者がビジネス開発に集中できるように、これらのインフラストラクチャとビジネスロジックの間の詳細を簡素化および分離するためにミドルウェアが導入されます。

ミドルウェアの動作は、特定のビジネス処理に入る前にフィルターに処理させるという Java のフィルターの動作原理に似ています。その動作モデルを次の図に示します。

Nodejsにおけるミドルウェアとは何ですか

ミドルウェア作業モデル

ミドルウェアメカニズムのコア実装

ミドルウェアは、HTTP リクエストから開始され、の応答の終了時の処理メソッドでは、通常、要求と応答の処理が必要となるため、基本的なミドルウェアは次の形式になります。

const middleware = (req, res, next) => {
  // TODO
  next()
}
ログイン後にコピー

以下は、2 つのミドルウェア メカニズムの実装を通じてミドルウェアを理解するものです。その仕組み。

方法 1

次のように 3 つの単純なミドルウェアを定義します。

const middleware1 = (req, res, next) => {
  console.log('middleware1 start')
  next()
}

const middleware2 = (req, res, next) => {
  console.log('middleware2 start')
  next()
}

const middleware3 = (req, res, next) => {
  console.log('middleware3 start')
  next()
}
ログイン後にコピー
// 中间件数组
const middlewares = [middleware1, middleware2, middleware3]
function run (req, res) {
  const next = () => {
    // 获取中间件数组中第一个中间件
    const middleware = middlewares.shift()
    if (middleware) {
      middleware(req, res, next)
    }
  }
  next()
}
run() // 模拟一次请求发起
ログイン後にコピー

上記のコードを実行すると、次のことがわかります。結果:

middleware1 start
middleware2 start
middleware3 start
ログイン後にコピー
ログイン後にコピー

ミドルウェアに非同期操作がある場合、非同期操作プロセスの終了後に

next() メソッドを呼び出す必要があります。そうしないと、ミドルウェアを順番に実行できません。 middleware2 ミドルウェアを書き換えます:

const middleware2 = (req, res, next) => {
  console.log('middleware2 start')  new Promise(resolve => {
    setTimeout(() => resolve(), 1000)
  }).then(() => {
    next()
  })
}
ログイン後にコピー

実行結果は前と同じですが、middleware2 が非同期で完了した後に middleware3 が実行されます。

middleware1 start
middleware2 start
middleware3 start
ログイン後にコピー
ログイン後にコピー

ミドルウェアの中には、統計時間用のログミドルウェアなど、業務処理の前に実行するだけでなく、業務処理後にも実行する必要があるものがあります。方法 1 の場合、

next() が非同期操作の場合、現在のミドルウェアの他のコードをコールバックとして実行できません。したがって、next() メソッドの後続の操作は Promise オブジェクトにカプセル化でき、next.then() フォームはその内部で使用できます。ミドルウェアが業務処理を完了するまでのコールバック。 run() メソッドを次のように書き換えます:

function run (req, res) {
  const next = () => {
    const middleware = middlewares.shift()    if (middleware) {      // 将middleware(req, res, next)包装为Promise对象
      return Promise.resolve(middleware(req, res, next))
    }
  }
  next()
}
ログイン後にコピー

ミドルウェアの呼び出しメソッドは次のように書き換える必要があります:

const middleware1 = (req, res, next) => {
  console.log('middleware1 start')  // 所有的中间件都应返回一个Promise对象
  // Promise.resolve()方法接收中间件返回的Promise对象,供下层中间件异步控制
  return next().then(() => {
    console.log('middleware1 end')
  })
}
ログイン後にコピー
const middleware1 = (req, res, next) => {
    console.log('middleware1 start')    // 所有的中间件都应返回一个Promise对象
    // Promise.resolve()方法接收中间件返回的Promise对象,供下层中间件异步控制
    return next().then((res) => {
      console.log("1",res)      return 'middleware1 end';
    })
  }
  
  const middleware2 = (req, res, next) => {
    console.log('middleware2 start')    // 所有的中间件都应返回一个Promise对象
    // Promise.resolve()方法接收中间件返回的Promise对象,供下层中间件异步控制
    // console.log("next()",next())
    return next().then((res) => {
      console.log("2",res)      return 'middleware2 end'
    })
  }
  const middleware3 = (req, res, next) => {
    console.log('middleware3 start')    return next().then((res) => {
      console.log("3",res)      return 'middleware3 end'
    })
  }

const middlewares = [middleware1, middleware2, middleware3]function run (req, res) {
    const next = () => {
      const middleware = middlewares.shift()      if (middleware) {        //   console.log("next",next)
        // 将middleware(req, res, next)包装为Promise对象
        return Promise.resolve(middleware(req, res, next))
      }else {        return Promise.resolve("结束");
      }
    }
    next()
  }
run() // 模拟一次请求发起
ログイン後にコピー

結果:

async await 実装


const middleware1 = async (req, res, next) => {
    console.log('middleware1 start')
    let result = await next();
    console.log("1",result)
  }
  
  const middleware2 = async (req, res, next) => {
    console.log('middleware2 start')
    let result = await next();
    console.log("2",result)
    return 'middleware2 end';
  }
  const middleware3 = async (req, res, next) => {
    console.log('middleware3 start')
    let result = await next();
    console.log("3",result)
    return 'middleware3 end';
  }

const middlewares = [middleware1, middleware2, middleware3]

function run (req, res) {
    const next = () => {
      const middleware = middlewares.shift()
      if (middleware) {
        //   console.log("next",next)
        // 将middleware(req, res, next)包装为Promise对象
        return Promise.resolve(middleware(req, res, next))
      }else {
        return Promise.resolve("结束");
      }
    }
    next()
  }
run() // 模拟一次请求发起
ログイン後にコピー

上記は、ミドルウェア機構における複数の非同期ミドルウェアの呼び出しプロセスを説明しています。例外処理やルーティングなどのミドルウェアの仕組みも考慮する必要があります。

express

フレームワークでは、ミドルウェアは方法 1 で実装され、グローバル ミドルウェアと組み込みルーティング ミドルウェア内のリクエスト パスに従って定義されたミドルウェアが連携しますが、それらは連携します。業務で使用できない 処理が完了すると、現在のミドルウェアのコードが呼び出されます。 koa2フレームワークにおけるミドルウェアの実装方法は方法2であり、next()メソッドの戻り値をPromiseにカプセル化し、以降の非同期処理を容易にします。は、koa2 フレームワークによって提案されたオニオン リング モデルを実装します。つまり、ミドルウェアの各層は球に相当します。モデル全体を貫通する場合、各球は実際には 2 回貫通します。

Nodejsにおけるミドルウェアとは何ですかkoa2 ミドルウェア オニオン リング モデル

koa2

フレームワークのミドルウェア メカニズムは非常にシンプルかつエレガントです。フレームワークについては、こちらをご覧ください。 . 複数のミドルウェアを組み合わせるコアコード。

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) {
      // index会在next()方法调用后累加,防止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 ミドルウェア リストのアドレス: https://github.com/koajs/koa/wiki

概要

この記事では、主にミドルウェアの概念とその理由について紹介します。ミドルウェアとミドルウェア メカニズムのコア実装を紹介しました。ミドルウェア機構により、Web アプリケーションは優れたスケーラビリティと構成可能性を備えます。

ミドルウェアを実装する場合、単一のミドルウェアは十分にシンプルであり、単一の責任を持つ必要があります。各リクエストはミドルウェア関連のコードを呼び出すため、ミドルウェア コードは効率的であり、必要に応じて繰り返し取得したデータをキャッシュできる必要があります。異なるルートにミドルウェアを使用する場合は、異なるルートに異なるミドルウェアが適用されることも考慮する必要があります。

[推奨学習:「nodejs チュートリアル 」]

以上がNodejsにおけるミドルウェアとは何ですかの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

関連ラベル:
ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
最新の問題
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート