一区二区三区日韩精品-日韩经典一区二区三区-五月激情综合丁香婷婷-欧美精品中文字幕专区

分享

Node.js 中的異步 Generator 函數(shù)和 Websockets

 風聲之家 2021-03-19

前端大全 3天前

以下文章來源于大前端技術之路 ,作者浥陽

英文:Valeri Karpov ,翻譯:大前端技術之路 / 浥陽

異步 generator 函數(shù)是 ES2018 中新增的特性。Node.js 從 v10 版本增加了對異步 generator 函數(shù)的支持。異步 generator 函數(shù)看似一個相當小眾特性特性,但是卻為 node.js websocket 框架提供了一個靈巧的使用機會。

在這篇文章中,我將說明 Node.js websocket 框架將如何使用異步 generator 函數(shù)。

HTTP 框架分類

首先,想一下 Express 或 Hapi 之類的 HTTP 服務器框架。一般來說,大多數(shù) HTTP 服務器框架都屬于以下三種之一:

  1. 顯式響應。 在 Express 中發(fā)送一個 HTTP 響應,你必須調用 res.end(),res.json() 或者 res 對象上的一些其他方法。換句話說,你必須顯式調用一個方法來發(fā)送一個響應。

  2. 使用 return 隱式響應。 另一方面,Hapi 在 v17 中明確地刪除了 reply() 函數(shù),也就是說 Hapi 沒有等同于 res 的方式。如果需要發(fā)送一個響應。你只需在請求的處理方法中 return 一個返回值。之后 Hapi 就會將 return 的值封裝進一個 HTTP 響應中。

  3. 在適當?shù)奈恢眯薷捻憫?/strong>  Koa 使用了一種混合了以上兩種實現(xiàn)的獨特處理方式。你將以修改 ctx 對象的方式,替代調用 res 對象的方法來構建響應。

換句話說,一些 HTTP 框架要求你顯式調用方法來發(fā)送 HTTP 響應,另一些框架會提供給你一個可更改的 HTTP 響應對象,還有一些框架僅需要處理函數(shù)中 return 一個值。

Websockets 和 HTTP 的區(qū)別在于,Websockets 服務器可以在任何時間向 socket 推送消息,不管是不是基于某條消息的響應。也就是說,初級的 websocket 框架,例如 ws, 看起來很像 “顯式響應” 模式:你需要顯式調用一個方法用于發(fā)送一條消息。

然而,是否可以在保持允許消息多發(fā)這個優(yōu)點的同時,使 websockets 可以實現(xiàn)隱式響應?這就是異步 generator 產生的原因。

從服務器上讀取大塊數(shù)據(jù)

假設你有一個一次讀取一堆文檔的 Mongoose 指針,并且你希望用 websocket 在每一個文檔讀出時盡快將它發(fā)送出去。這種方式有助于在任何時刻都使服務器的內存使用量保持在最?。嚎蛻舳丝梢垣@取所有的數(shù)據(jù),而服務器卻不用為此在內存中一次保存所有的數(shù)據(jù)。舉個例子,這是使用 async/await 方式讀取一個指針的實現(xiàn):

const User = mongoose.model('User', mongoose.Schema({ nameString }));

const cursor = Model.find().cursor();
for await (const doc of cursor) {
  console.log(doc.name); // Print user names 1 by 1.
}

使 generator 函數(shù)變得有趣的地方在于,在一個函數(shù)中 yield 方法可以被調用多次,并且在上次停止的地方繼續(xù)運行,除了這點以外,yield 方法和 return 方法類似。

const User = mongoose.model('User', mongoose.Schema({ nameString }));

async functionstreamUsers({
  const cursor = Model.find().cursor();
  for await (const doc of cursor) {
    // Yielding each doc behaves like multiple implicit responses, if you have
    // a framework that supports it.
    yield doc;
  }
}

以下是如何使用 Node.js 編寫一個 Websocket 服務器:

const WebSocket = require('ws');
const server = new WebSocket.Server({
  port8080
});

server.on('connection'function(socket{
  socket.on('message'function(msg{
    // Handle message
  });
});

至此,接下來要做的是為 websocket 服務器添加 streamUsers() 方法。假設收到的每條消息都是有效的 JSON,并且都有屬性 action 和 id。當 action === 'streamUsers'時,streamUsers() 就會被執(zhí)行,并且基于 socket 向外發(fā)送每個被 Mongoose cursor 查詢出來的用戶。

const WebSocket = require('ws');
const server = new WebSocket.Server({
  port8080
});

server.on('connection'function(socket{
  socket.on('message'function(msg{
    msg = JSON.parse(msg);

    if (msg.action === 'streamUsers') {
      void async function({
        // Send 1 message per user, as opposed to loading all users and then
        // sending them all in 1 message.
        for await (const doc of streamUsers()) {
          socket.send(JSON.stringify({ id: msg.id, doc }));
        }
      }().catch(err => socket.send(JSON.stringify({ id: msg.id, error: err.message })));
    }
  });
});

以下是如何通過 websocket 客戶端調用 streamUsers() 方法:

const client = new WebSocket('ws://localhost:8080');

// Will print each user doc 1 at a time.
client.on('message', msg => console.log(msg));

await new Promise(resolve => client.once('open', resolve));

client.send(JSON.stringify({ action'streamUsers'id1 }));

后續(xù)

異步 generator 函數(shù)提供了一種創(chuàng)建更高級的,如同一些 HTTP 框架(例如 Hapi 和 Fastify)那樣,基于隱式響應的 websocket 框架的機會。而隱式響應的主要優(yōu)勢就在于,你在業(yè)務邏輯中不需要關注框架是通過 websocket,HTTP 輪詢或是其他某種方式來發(fā)送結果。框架自由式 Javascript 編程更輕便并且更容易測試。

通過將所有產生的值存放在一個數(shù)組中,或者讓客戶端發(fā)起多次請求對一個指針進行迭代,streamUsers() 方法就可以很容易的在一個 HTTP 框架,或者是一個使用輪詢的 HTTP 框架中重用。沒有異步 generator 函數(shù),所有這些都是不能實現(xiàn)的。

- EOF -

    本站是提供個人知識管理的網絡存儲空間,所有內容均由用戶發(fā)布,不代表本站觀點。請注意甄別內容中的聯(lián)系方式、誘導購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權內容,請點擊一鍵舉報。
    轉藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多

    欧美人妻少妇精品久久性色| 国产精品第一香蕉视频| 国产伦精品一区二区三区高清版| 国产精品久久女同磨豆腐| 色哟哟哟在线观看视频| 日韩人妻有码一区二区| 欧美大粗爽一区二区三区 | 中文字幕五月婷婷免费| 东京热男人的天堂一二三区| 欧美中文字幕日韩精品| 国产丝袜极品黑色高跟鞋| 国产剧情欧美日韩中文在线| 国产福利一区二区久久| 国产精品亚洲欧美一区麻豆| 精品伊人久久大香线蕉综合 | 色丁香一区二区黑人巨大| 综合久综合久综合久久| 久久精品亚洲精品国产欧美| 国内胖女人做爰视频有没有| 国产欧美一区二区久久| 亚洲少妇人妻一区二区| 色综合伊人天天综合网中文| 日本不卡在线一区二区三区| 丰满熟女少妇一区二区三区| 白白操白白在线免费观看| 亚洲欧美日本视频一区二区| 黑人巨大精品欧美一区二区区 | 国产午夜福利不卡片在线观看| 日韩欧美一区二区久久婷婷| 亚洲婷婷开心色四房播播| 91亚洲国产成人久久精品麻豆| 欧美日韩亚洲国产精品| 国产精品丝袜美腿一区二区| 亚洲天堂一区在线播放| 国产乱人伦精品一区二区三区四区 | 国产又粗又黄又爽又硬的| 欧美午夜视频免费观看| 麻豆视传媒短视频在线看| 午夜午夜精品一区二区| 国产欧美精品对白性色| 日本高清一道一二三区四五区|