成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

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

開發(fā) 前端
在這篇文章中,我將說(shuō)明 Node.js websocket 框架將如何使用異步 generator 函數(shù)。

[[387974]]

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

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

HTTP 框架分類

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

    1.  顯式響應(yīng)。 在 Express 中發(fā)送一個(gè) HTTP 響應(yīng),你必須調(diào)用 res.end(),res.json() 或者 res 對(duì)象上的一些其他方法。換句話說(shuō),你必須顯式調(diào)用一個(gè)方法來(lái)發(fā)送一個(gè)響應(yīng)。

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

    3.  在適當(dāng)?shù)奈恢眯薷捻憫?yīng)。  Koa 使用了一種混合了以上兩種實(shí)現(xiàn)的獨(dú)特處理方式。你將以修改 ctx 對(duì)象的方式,替代調(diào)用 res 對(duì)象的方法來(lái)構(gòu)建響應(yīng)。

換句話說(shuō),一些 HTTP 框架要求你顯式調(diào)用方法來(lái)發(fā)送 HTTP 響應(yīng),另一些框架會(huì)提供給你一個(gè)可更改的 HTTP 響應(yīng)對(duì)象,還有一些框架僅需要處理函數(shù)中 return 一個(gè)值。

Websockets 和 HTTP 的區(qū)別在于,Websockets 服務(wù)器可以在任何時(shí)間向 socket 推送消息,不管是不是基于某條消息的響應(yīng)。也就是說(shuō),初級(jí)的 websocket 框架,例如 ws, 看起來(lái)很像 “顯式響應(yīng)” 模式:你需要顯式調(diào)用一個(gè)方法用于發(fā)送一條消息。

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

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

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

  1. const User = mongoose.model('User', mongoose.Schema({ name: String }));  
  2. const cursor = Model.find().cursor();  
  3. for await (const doc of cursor) {  
  4.   console.log(doc.name); // Print user names 1 by 1.  

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

  1. const User = mongoose.model('User', mongoose.Schema({ name: String }));  
  2. async function* streamUsers() {  
  3.   const cursor = Model.find().cursor();  
  4.   for await (const doc of cursor) {  
  5.     // Yielding each doc behaves like multiple implicit responses, if you have  
  6.     // a framework that supports it.  
  7.     yield doc;  
  8.   }  

以下是如何使用 Node.js 編寫一個(gè) Websocket 服務(wù)器: 

  1. const WebSocket = require('ws');  
  2. const server = new WebSocket.Server({  
  3.   port: 8080  
  4. });  
  5. server.on('connection', function(socket) {  
  6.   socket.on('message', function(msg) {  
  7.     // Handle message 
  8.   });  
  9. }); 

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

  1. const WebSocket = require('ws');  
  2. const server = new WebSocket.Server({  
  3.   port: 8080  
  4. });  
  5. server.on('connection', function(socket) { 
  6.   socket.on('message', function(msg) {  
  7.     msg = JSON.parse(msg);  
  8.     if (msg.action === 'streamUsers') {  
  9.       void async function() {  
  10.         // Send 1 message per user, as opposed to loading all users and then  
  11.         // sending them all in 1 message.  
  12.         for await (const doc of streamUsers()) {  
  13.           socket.send(JSON.stringify({ id: msg.id, doc })); 
  14.          }  
  15.       }().catch(err => socket.send(JSON.stringify({ id: msg.id, error: err.message })));  
  16.     }  
  17.   });  
  18. }); 

以下是如何通過(guò) websocket 客戶端調(diào)用 streamUsers() 方法: 

  1. const client = new WebSocket('ws://localhost:8080');  
  2. // Will print each user doc 1 at a time.  
  3. client.on('message', msg => console.log(msg));  
  4. await new Promise(resolve => client.once('open', resolve));  
  5. client.send(JSON.stringify({ action: 'streamUsers', id: 1 })); 

后續(xù)

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

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

 

責(zé)任編輯:龐桂玉 來(lái)源: 前端大全
相關(guān)推薦

2021-03-04 23:12:57

Node.js異步迭代器開發(fā)

2021-04-06 10:15:29

Node.jsHooks前端

2013-08-15 09:14:55

2011-12-23 13:58:57

node.js

2025-01-13 00:00:00

2020-12-08 06:28:47

Node.js異步迭代器

2021-10-22 08:29:14

JavaScript事件循環(huán)

2021-04-20 12:39:52

Node.js多線程多進(jìn)程

2021-08-04 23:30:28

Node.js開發(fā)線程

2021-05-21 09:36:42

開發(fā)技能代碼

2016-08-11 14:02:02

NodeJS前端

2020-04-15 15:48:03

Node.jsstream前端

2024-01-05 08:49:15

Node.js異步編程

2021-01-26 08:07:44

Node.js模塊 Async

2013-11-01 09:34:56

Node.js技術(shù)

2015-03-10 10:59:18

Node.js開發(fā)指南基礎(chǔ)介紹

2019-07-09 14:50:15

Node.js前端工具

2017-03-19 16:40:28

漏洞Node.js內(nèi)存泄漏

2017-03-20 13:43:51

Node.js內(nèi)存泄漏

2021-12-25 22:29:57

Node.js 微任務(wù)處理事件循環(huán)
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

主站蜘蛛池模板: 二区精品| 久久久久亚洲精品 | 日本精品网站 | 国产精品视频一二三区 | 瑟瑟免费视频 | 日韩一区二区福利视频 | 欧美日本在线观看 | 狠狠操电影 | 国产综合精品 | 一本一道久久a久久精品蜜桃 | 亚洲精品久久久久久首妖 | 久草视频在 | 亚洲欧美视频一区二区 | 久久噜噜噜精品国产亚洲综合 | 日韩一区二区在线视频 | 亚洲一区二区三区免费观看 | 久久小视频 | 古装三级在线播放 | 国产精品99久久久久久动医院 | 日日爱视频 | 欧美日产国产成人免费图片 | 国产精品视频入口 | 奇米影视在线 | 高清色视频| 亚洲免费视频播放 | 欧美日本久久 | 久久四虎| h片在线免费看 | 久久久高清 | 中文字幕欧美在线观看 | 欧美精品福利 | 成人黄色av网址 | 精品福利一区 | 81精品国产乱码久久久久久 | 精品久久影院 | 国产亚洲精品久久久优势 | 四虎影视免费观看 | 黄色片a级 | 国产免费一区二区三区最新6 | 操到爽| 免费在线观看一区二区三区 |