最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

淺談Express異步進化史

 更新時間:2017年09月09日 14:18:22   作者:幻天芒  
本篇文章主要介紹了淺談Express異步進化史 ,小編覺得挺不錯的,現在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧

1、導言

在 Javascript 的世界里,異步(由于JavaScript的單線程運行,所以JavaScript中的異步是可以阻塞的)無處不在。

Express 是 node 環(huán)境中非常流行的Web服務端框架,有很大比例的 Node Web應用 采用了 Express。

當使用 JavaScript 編寫服務端代碼時,我們無可避免的會大量使用到異步。隨著 JavaScript、Node 的進化,我們的異步處理方式,也就隨之進化。

接下來,我們就來看看 Express 中異步處理的進化過程。

2、JavaScript的異步處理

在異步的世界里,我們需要想辦法獲取的異步方法完畢的通知,那在 JavaScript 中,會有哪些方式呢?

2.1、回調

回調是 JS 中最原始,也是最古老的異步通知機制。

function asyncFn(callback) {
 // 利用setTimeout模擬異步
 setTimeout(function () {
  console.log('執(zhí)行完畢');
  callback(); // 發(fā)通知
 }, 2000);
}

asyncFn(function () {
 console.log('我會在2s后輸出');
});

2.2、事件監(jiān)聽

要獲取結果的函數,監(jiān)聽某個時間。在異步方法完成后,觸發(fā)該事件,達到通知的效果。

2.3、發(fā)布/訂閱

通過觀察者模式,在異步完成時,修改發(fā)布者。這個時候,發(fā)布者會把變更通知到訂閱者。

2.4、Promise

Promise 是回調函數的改進。使用它, 我們可以將異步平行化,避免回調地獄。

function asyncFn() {
 return new Promise((resolve, reject) => {
  // 利用setTimeout模擬異步
  setTimeout(function () {
   console.log('執(zhí)行完畢');
   resolve(); // 發(fā)通知(是否有感覺到回調的影子?)
  }, 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('執(zhí)行完畢');
   resolve(); // 發(fā)通知(是否有感覺到回調的影子?)
  }, 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('執(zhí)行完畢');
   resolve(); // 發(fā)通知(是否有感覺到回調的影子?)
  }, 2000);
 });
}

async function run(){
 await asyncFn();
 console.log('我會在2s后輸出');
}

run();

3、Express中的異步處理

在Express中,我們一般常用的是方案是:回調函數、Promise、以及async...await。

為了搭建演示環(huán)境,通過 express-generator 初始化一個express項目。一般的服務端項目,都是路由調用業(yè)務邏輯。所以,我們也遵循這個原則:

打開 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 中,路由可以加載多個中間件,所以我們可以把業(yè)務邏輯按照中間件的寫法進行編寫。這樣通過一層層的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); // 一步步執(zhí)行中間件

module.exports = router;

3.2、Promise 處理Express異步邏輯

該方案中,將多個業(yè)務邏輯,包裝為返回 Promise 的函數。通過業(yè)務方法進行組合調用,以達到一進一出的效果。

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); // 統(tǒng)一異常處理
};

/* 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 龐大的生態(tài)圈,無異于如虎添翼。

本文Github地址

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。

相關文章

  • Node 搭建一個靜態(tài)資源服務器的實現

    Node 搭建一個靜態(tài)資源服務器的實現

    這篇文章主要介紹了Node 搭建一個靜態(tài)資源服務器的實現,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2019-05-05
  • Node.js 中 morgan 依賴及基本使用詳解

    Node.js 中 morgan 依賴及基本使用詳解

    文章介紹了Node.js中`morgan`依賴的安裝、基本使用、日志格式(如`dev`、`combined`、`common`等),以及如何自定義日志格式和將日志寫入文件,感興趣的朋友一起看看吧
    2025-02-02
  • 詳細分析Node.js 模塊系統(tǒng)

    詳細分析Node.js 模塊系統(tǒng)

    這篇文章主要介紹了Node.js 模塊系統(tǒng)的的相關資料,文中講解非常詳細,供大家參考和學習,感興趣的朋友可以了解下
    2020-06-06
  • 如何利用Node.js做簡單的圖片爬取

    如何利用Node.js做簡單的圖片爬取

    這篇文章主要介紹了如何利用Node.js做簡單的圖片爬取,爬蟲的主要目的是收集互聯網上公開的一些特定數據,本文介紹用于網絡抓取的node.js包,完成一個簡單的爬蟲案例來爬取網頁上圖片并下載到本地
    2022-06-06
  • Express下采用bcryptjs進行密碼加密的方法

    Express下采用bcryptjs進行密碼加密的方法

    本篇文章主要介紹了Express下采用bcryptjs進行密碼加密的方法,小編覺得挺不錯的,現在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-02-02
  • node異步使用await和不用await的區(qū)別實例分析

    node異步使用await和不用await的區(qū)別實例分析

    這篇文章主要介紹了node異步使用await和不用await的區(qū)別,結合實例形式分析了node.js異步使用await和不用await的實例中,同步與異步執(zhí)行的區(qū)別,需要的朋友可以參考下
    2023-06-06
  • node+koa2+mysql+bootstrap搭建一個前端論壇

    node+koa2+mysql+bootstrap搭建一個前端論壇

    本篇文章通過實例給大家分享了用node+koa2+mysql+bootstrap搭建一個前端論壇的步驟,有需要的朋友參考下。
    2018-05-05
  • node.js中fs.stat與fs.fstat的區(qū)別詳解

    node.js中fs.stat與fs.fstat的區(qū)別詳解

    fs.stat和fs.fstat他們都是用來獲取文件的狀態(tài)信息,下面這篇文章主要給大家介紹了關于node.js中fs.stat與fs.fstat區(qū)別的相關資料,文中介紹的非常詳細,對大家具有一定的參考學習價值,需要的朋友們下面來一起看看吧。
    2017-06-06
  • node.js如何操作MySQL數據庫

    node.js如何操作MySQL數據庫

    這篇文章主要介紹了node.js如何操作MySQL數據庫,幫助大家更好的進行web開發(fā),感興趣的朋友可以了解下
    2020-10-10
  • Nodejs處理Json文件并將處理后的數據寫入新文件中

    Nodejs處理Json文件并將處理后的數據寫入新文件中

    這篇文章主要介紹了Nodejs處理Json文件并將處理后的數據寫入新文件中,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-10-10

最新評論

蒙城县| 寿阳县| 徐汇区| 赣榆县| 玛多县| 四平市| 湛江市| 盘山县| 寿宁县| 蒙山县| 深泽县| 徐汇区| 嘉兴市| 山东省| 西盟| 和顺县| 长乐市| 霍山县| 莒南县| 弥渡县| 察隅县| 江门市| 濮阳县| 五常市| 体育| 扎鲁特旗| 庄河市| 刚察县| 萍乡市| 哈巴河县| 威信县| 宜春市| 调兵山市| 区。| 兖州市| 寿光市| 清原| 怀宁县| 蓝山县| 舟山市| 揭阳市|