首頁 web前端 js教程 nodejs操作express中的next

nodejs操作express中的next

Apr 18, 2018 am 11:20 AM
express javascript nodejs

這次帶給大家nodejs操作express中的next,nodejs操作express中next的注意事項有哪些,下面就是實戰案例,一起來看一下。

相信很多人對於nodejs對express中next不是很了解,大多數人不知道其中的next有什麼作用,在什麼情況下使用,今天文章中就給大家詳細介紹下其使用方法,感興趣的一起來了解下。

最近公司在使用node做前後端分離,採用的web框架是express,所以對express框架進行了深入的了解,前段時間寫了篇關於express路由的文章,但是在那篇文章中貌似少了一個很重要的內容,就是express的next,所以今天單獨來談談express的next。

關於next主要從三點來進行說明:

  • # next的作用是什麼?

  • 我們應該在何時使用next?

  • next的內部實作機制是什麼?

Next的作用

我們在定義express中間件函數的時候都會將第三個參數定義為next,這個next就是我們今天的主角,next函數主要負責將控制權交給下一個中間件,如果當前中間件沒有終結請求,且next沒有被調用,那麼請求將被掛起,後邊定義的中間件將不會得到被執行的機會。

何時使用Next

從上邊的描述我們已經知道,next函數主要是用來確保所有註冊的中間件被一個接一個的執行,那麼我們就應該在所有的中間件中調用next函數,但有一個特例,如果我們定義的中間件終結了本次請求,那就不應該再呼叫next函數,否則就可能會出問題,我們來看段碼

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: {}
 });
});
登入後複製

發送請求"/a",控制台列印日誌如下:

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)
登入後複製

為什麼程式碼會拋異常呢,就是因為我們在res.send之後呼叫了next函數,雖然我們本次的請求已經被終止,但後邊的404中間件依舊會被執行,而後邊的中間件試圖去向res的headers中加入屬性值,所以就會拋出上邊的異常。

讀到這裡你可能會有個疑問,如果我不在res.send後邊呼叫next函數,那後邊定義的404中間件是不是永遠都不會被執行到。現在我們刪除res.send後邊next函數調用,發送請求"/xxx",我們會發現404中間件被執行了,(ㄒoㄒ),這不是和我們之前說的矛盾了嗎,我們的自定義中間件沒有呼叫next,但後邊定義的中間件仍舊被執行了,這究竟是為什麼呢。看來只能求助原始碼了~~~

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);
  }
 }
登入後複製

上邊就是express中next的源碼,為了更容易說明問題,程式碼進行了刪減。從上邊的源碼可以發現,next函數內部有個while循環,每次循環都會從stack中拿出一個layer,這個layer中包含了路由和中間件信息,然後就會用layer和請求的path就行匹配,如果匹配成功就會執行layer.handle_request,呼叫中間件函數。但如果匹配失敗,就會循環下一個layer(即中間件)。

現在我們就能解釋上邊提出的問題了,為什麼我們的自訂中間件中沒呼叫next函數,但後邊的404中間件仍舊會被執行到,因為我們請求的"/xxx"匹配不到我們註冊的"/a"路由中間件,所以while循環會繼續往下執行,匹配404中間件成功,所以會執行404中間件。

注意:app.use註冊的中間件,如果path參數為空,則預設為"/",而path為"/"的中間件則預設符合所有的請求。

有一點需要特別指出,其實我們在定義路由中間件的時候函數的第三個參數next和我們定義非路由中間件的函數的第三個參數next不是同一個next,我們在上邊看到的是非路由中間件的next,而路由中間件的next函數是這樣的

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面向对象深入理解

以上是nodejs操作express中的next的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱門文章

R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
1 個月前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳圖形設置
1 個月前 By 尊渡假赌尊渡假赌尊渡假赌
威爾R.E.P.O.有交叉遊戲嗎?
1 個月前 By 尊渡假赌尊渡假赌尊渡假赌

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

nodejs是後端框架嗎 nodejs是後端框架嗎 Apr 21, 2024 am 05:09 AM

Node.js 可作為後端框架使用,因為它提供高效能、可擴展性、跨平台支援、豐富的生態系統和易於開發等功能。

nodejs怎麼連接mysql資料庫 nodejs怎麼連接mysql資料庫 Apr 21, 2024 am 06:13 AM

要連接 MySQL 資料庫,需要遵循以下步驟:安裝 mysql2 驅動程式。使用 mysql2.createConnection() 建立連接對象,其中包含主機位址、連接埠、使用者名稱、密碼和資料庫名稱。使用 connection.query() 執行查詢。最後使用 connection.end() 結束連線。

nodejs安裝目錄裡的npm與npm.cmd檔有什麼差別 nodejs安裝目錄裡的npm與npm.cmd檔有什麼差別 Apr 21, 2024 am 05:18 AM

Node.js 安裝目錄中有兩個與 npm 相關的文件:npm 和 npm.cmd,區別如下:擴展名不同:npm 是可執行文件,npm.cmd 是命令視窗快捷方式。 Windows 使用者:npm.cmd 可以在命令提示字元中使用,npm 只能從命令列執行。相容性:npm.cmd 特定於 Windows 系統,npm 跨平台可用。使用建議:Windows 使用者使用 npm.cmd,其他作業系統使用 npm。

nodejs中的全域變數有哪些 nodejs中的全域變數有哪些 Apr 21, 2024 am 04:54 AM

Node.js 中存在以下全域變數:全域物件:global核心模組:process、console、require執行階段環境變數:__dirname、__filename、__line、__column常數:undefined、null、NaN、Infinity、-Infinity

nodejs和java的差別大嗎 nodejs和java的差別大嗎 Apr 21, 2024 am 06:12 AM

Node.js 和 Java 的主要差異在於設計和特性:事件驅動與執行緒驅動:Node.js 基於事件驅動,Java 基於執行緒驅動。單執行緒與多執行緒:Node.js 使用單執行緒事件循環,Java 使用多執行緒架構。執行時間環境:Node.js 在 V8 JavaScript 引擎上運行,而 Java 在 JVM 上運行。語法:Node.js 使用 JavaScript 語法,而 Java 使用 Java 語法。用途:Node.js 適用於 I/O 密集型任務,而 Java 適用於大型企業應用程式。

nodejs是後端開發語言嗎 nodejs是後端開發語言嗎 Apr 21, 2024 am 05:09 AM

是的,Node.js 是一種後端開發語言。它用於後端開發,包括處理伺服器端業務邏輯、管理資料庫連接和提供 API。

nodejs專案怎麼部署到伺服器 nodejs專案怎麼部署到伺服器 Apr 21, 2024 am 04:40 AM

Node.js 專案的伺服器部署步驟:準備部署環境:取得伺服器存取權限、安裝 Node.js、設定 Git 儲存庫。建置應用程式:使用 npm run build 產生可部署程式碼和相依性。上傳程式碼到伺服器:透過 Git 或檔案傳輸協定。安裝依賴項:SSH 登入伺服器並使用 npm install 安裝應用程式相依性。啟動應用程式:使用 node index.js 等命令啟動應用程序,或使用 pm2 等進程管理器。設定反向代理(可選):使用 Nginx 或 Apache 等反向代理路由流量到應用程式

nodejs和java選哪個 nodejs和java選哪個 Apr 21, 2024 am 04:40 AM

Node.js 和 Java 在 Web 開發中各有優劣,因此選擇取決於專案需求。 Node.js 擅長即時應用程式、快速開發和微服務架構,而 Java 則在企業級支援、效能和安全性方面佔優。

See all articles