Express發展歷程
這篇文章主要介紹了淺談Express非同步進化史 ,小編覺得挺不錯的,現在分享給大家,也給大家做個參考。一起跟著小編過來看看吧
1、導言
在Javascript 的世界裡,非同步(由於JavaScript的單執行緒運行,所以JavaScript中的非同步是可以阻塞的)無所不在。
Express 是 node 環境中非常流行的Web服務端框架,有很大比例的 Node Web應用 採用了 Express。
當使用 JavaScript 編寫服務端程式碼時,我們無可避免的會大量使用到非同步。隨著 JavaScript、Node 的演化,我們的非同步處理方式,也隨之進化。
接下來,我們就來看看 Express 中非同步處理的演化過程。
2、JavaScript的非同步處理
#在非同步的世界裡,我們需要想辦法取得的非同步方法完畢的通知,那在JavaScript 中,會有哪些方式呢?
2.1、回呼
#回呼是 JS 中最原始,也是最古老的非同步通知機制。
function asyncFn(callback) { // 利用setTimeout模拟异步 setTimeout(function () { console.log('执行完毕'); callback(); // 发通知 }, 2000); } asyncFn(function () { console.log('我会在2s后输出'); });
2.2、事件監聽
要取得結果的函數,監聽某個時間。在非同步方法完成後,觸發該事件,達到通知的效果。
2.3、發布/訂閱
透過觀察者模式,在非同步完成時,修改發布者。這時候,發布者會把變更通知訂閱者。
2.4、Promise
Promise 是回呼函數的改進。使用它, 我們可以將非同步平行化,避免回調地獄。
function asyncFn() { return new Promise((resolve, reject) => { // 利用setTimeout模拟异步 setTimeout(function () { console.log('执行完毕'); resolve(); // 发通知(是否有感觉到回调的影子?) }, 2000); }); } asyncFn() .then(function () { console.log('我会在2s后输出'); });
2.5、生成器(Generator)
Generator 函數是 ES6 提供的一個非同步程式解決方案。
以下程式碼只是簡單演示,實際上 Generator 的使用過程,相對是比較複雜的,這是另外一個話題,本文暫且不表。
function asyncFn() { return new Promise((resolve, reject) => { // 利用setTimeout模拟异步 setTimeout(function () { console.log('执行完毕'); resolve(); // 发通知(是否有感觉到回调的影子?) }, 2000); }); } function* generatorSync() { var result = yield asyncFn(); } var g = generatorSync(); g.next().value.then(()=>{ console.log('我会在2s后输出'); });
2.6、async...await
可以說是目前 JavaScript 中,處理非同步的最佳方案。
function asyncFn() { return new Promise((resolve, reject) => { // 利用setTimeout模拟异步 setTimeout(function () { console.log('执行完毕'); resolve(); // 发通知(是否有感觉到回调的影子?) }, 2000); }); } async function run(){ await asyncFn(); console.log('我会在2s后输出'); } run();
3、Express中的非同步處理
在Express中,我們一般常用的是方案是:回呼函數、Promise、以及async...await。
為了建構示範環境,透過 express-generator 初始化一個express專案。一般的服務端項目,都是路由呼叫業務邏輯。所以,我們也遵循這個原則:
開啟 routs/index.js,我們會看到如下內容,以下Demo就以此文件來做示範。
var express = require('express'); var router = express.Router(); /* GET home page. */ router.get('/', function(req, res, next) { res.render('index', { title: 'Express' }); }); module.exports = router;
3.1、回呼函數處理Express非同步邏輯
在Express 中,路由可以載入多個中間件,所以我們可以把業務邏輯依照中間件的寫法進行編寫。這樣透過一層層的next,就能非常方便的分割非同步邏輯。
var express = require('express'); var router = express.Router(); function asyncFn(req, res, next) { setTimeout(() => { req.user = {}; // 设置当前请求的用户 next(); }, 2000); } function asyncFn2(req, res, next) { setTimeout(() => { req.auth = {}; // 设置用户权限 next(); }, 2000); } function asyncFn3(req, res, next) { setTimeout(() => { res.locals = { title: 'Express Async Test' }; // 设置数据 res.render('index'); // 响应 }, 2000); } /* GET home page. */ router.get('/', asyncFn, asyncFn2, asyncFn3); // 一步步执行中间件 module.exports = router;
3.2、Promise 處理Express非同步邏輯
該方案中,將多個業務邏輯,包裝為傳回Promise 的函數。透過業務方法進行組合調用,以達到一進一出的效果。
var express = require('express'); var router = express.Router(); function asyncFn(req, res) { return new Promise((resolve, reject) => { setTimeout(() => { req.user = {}; // 设置当前请求的用户 resolve(req); }, 2000); }); } function asyncFn2(req) { return new Promise((resolve, reject) => { setTimeout(() => { req.auth = {}; // 设置用户权限 resolve(); }, 2000); }); } function asyncFn3(res) { return new Promise((resolve, reject) => { setTimeout(() => { res.locals = { title: 'Express Async Test' }; // 设置数据 res.render('index'); // 响应 }, 2000); }); } function doBizAsync(req, res, next) { asyncFn(req) .then(() => asyncFn2(req)) .then(() => asyncFn3(res)) .catch(next); // 统一异常处理 }; /* GET home page. */ router.get('/', doBizAsync); module.exports = router;
3.3、async...await 處理Express非同步邏輯
實際上,該方案也是需要Promise 的支持,只是寫法上,更直觀,錯誤處理也更直接。
要注意的是,Express是早期的方案,沒有對async...await進行全域錯誤處理,所以可以採用包裝方式,進行處理。
var express = require('express'); var router = express.Router(); function asyncFn(req) { return new Promise((resolve, reject) => { setTimeout(() => { req.user = {}; // 设置当前请求的用户 resolve(req); }, 2000); }); } function asyncFn2(req) { return new Promise((resolve, reject) => { setTimeout(() => { req.auth = {}; // 设置用户权限 resolve(); }, 2000); }); } function asyncFn3(res) { return new Promise((resolve, reject) => { setTimeout(() => { }, 2000); }); } async function doBizAsync(req, res, next) { var result = await asyncFn(req); var result2 = await asyncFn2(req); res.locals = { title: 'Express Async Test' }; // 设置数据 res.render('index'); // 响应 }; const tools = { asyncWrap(fn) { return (req, res, next) => { fn(req, res, next).catch(next); // async...await在Express中的错误处理 } } }; /* GET home page. */ router.get('/', tools.asyncWrap(doBizAsync)); // 需要用工具方法包裹一下 module.exports = router;
4、總結
#雖然koa 對更新、更好的用法(koa是generator ,koa2原生async)支援的更好。但作為從 node 0.x 開始跟隨的我,對 Express 還是有特殊的好感。
以上的一些方案,已經與 koa 中使用無異,配合 Express 龐大的生態圈,無異於如虎添翼。
本文Github位址
#以上是Express發展歷程的詳細內容。更多資訊請關注PHP中文網其他相關文章!

熱AI工具

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

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

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

AI Hentai Generator
免費產生 AI 無盡。

熱門文章

熱工具

記事本++7.3.1
好用且免費的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強大的PHP整合開發環境

Dreamweaver CS6
視覺化網頁開發工具

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

熱門話題

怎麼處理文件上傳?以下這篇文章為大家介紹一下node專案中如何使用express來處理文件的上傳,希望對大家有幫助!

深入比較Express和Laravel:如何選擇最佳框架?在選擇一個適合自己專案的後端框架時,Express和Laravel無疑是兩個備受開發者歡迎的選擇。 Express是基於Node.js的輕量級框架,而Laravel則是基於PHP的流行框架。本文將深入比較這兩個框架的優缺點,並提供具體的程式碼範例,以幫助開發者選擇最適合自己需求的框架。效能和擴展性Expr

Express和Laravel是兩個非常受歡迎的Web框架,分別代表了JavaScript和PHP兩大開發語言的優秀框架。本文將針對這兩個架構進行比較分析,幫助開發者選擇更適合自己專案需求的框架。一、框架簡介Express是一個基於Node.js平台的Web應用程式框架,它提供了一系列強大的功能和工具,使開發者可以快速建立高效能的網路應用程式。 Express

Golang(簡稱Go語言)作為一種程式語言在近年來逐漸在區塊鏈領域嶄露頭角,其高效的並發處理能力和簡潔的語法特點使其成為了區塊鏈開發中備受青睞的一種選擇。本文將探討Golang如何協助區塊鏈發展,並透過具體的程式碼範例展示其在區塊鏈應用中的優越性。一、Golang在區塊鏈領域的優勢高效的並發處理能力:區塊鏈系統中的節點需要同時處理大量的事務和數據,而Gola

標題:C語言的起源和發展歷史C語言是一種廣泛應用於系統軟體和應用軟體開發的高階程式語言。它具有結構化、模組化和可移植性等特點,是電腦領域中最為重要和流行的程式語言之一。本文將介紹C語言的起源和發展歷史,並結合具體的程式碼範例進行說明。一、C語言的起源C語言的歷史可以追溯到1969年,當時貝爾實驗室的DennisRitchie和KenThompson為了開

隨著科技的快速發展和資訊科技在教育領域的廣泛應用,Canvas作為一種全球領先的線上學習管理系統,正逐漸在中國教育界嶄露頭角。 Canvas的出現,為中國教育教學方式的改革提供了新的可能性。本文將探討Canvas在中國教育界的發展趨勢及前景。首先,Canvas在中國教育界的發展趨勢之一是深度融合。隨著雲端運算、大數據和人工智慧的快速發展,Canvas將越來越多地

Golang,也稱為Go語言,是由Google開發的程式語言,是一種同時進行程式設計和網路程式設計的高階程式語言。近年來,隨著雲端運算技術的快速發展,Golang在雲端運算領域的應用也逐漸受到重視。本文將探討Golang如何協助雲端運算發展,透過具體的程式碼範例來說明其在雲端運算領域的優勢和應用。一、Golang在雲端運算中的優勢並發程式設計能力:Golang天生就具備強大的並發

從ChatGPT到AI畫圖技術,人工智慧領域最近的這波突破或許都要感謝Transformer。今天是著名的transformer論文提交六週年的日子。論文連結:https://arxiv.org/abs/1706.03762六年前,一篇名字有點浮誇的論文被上傳到了預印版論文平台arXiv上,「xxisAllYouNeed」這句話被AI領域的開發者們不斷複述,甚至已經成了論文標題的潮流,Transformer也不再是變形金剛的意思,它現在代表著AI領域最先進的技術。六年後,回看當年的這篇論文
