【ECMAScript】WebSocket模拟HTTP功能的实践:Promise+WebSocket+EventEmitter+Queue

1. 前言

        本篇将结合Promise、WebSocket、EventEmitter和Queue,做一次实践:用WebSocket来模拟HTTP的功能。先不用关心它的用处,就当一次对知识点的整合吧。

2. MockHTTP
方法说明
request(params, callback?)

功能:发起请求,生成uuid标记数据params,将回调逻辑once到事件发射器中,返回一个Promise对象,等待receive触发emit,执行回调逻辑

输入

params - 发送给服务端的数据

callback? - 可选,采用回调函数方式接收数据

输出:Promise<any>

send(params)

功能:将数据推入队列中,待loop取出

输入:params

loop()功能:定时从队列队头取出数据,发给服务端
receive(e)

功能:接收响应数据,触发事件发射器emit方法

输入:e - 事件对象

close()功能:关闭WebSocket连接

import EventEmitter from './EventEmiter';
import Queue from './Queue';export default class MockHTTP {constructor(url) {this.ws = new WebSocket(url);this.eventEmitter = new EventEmitter();this.queue = new Queue();this.ws.onmessage = this.receive;}loop() {if(this.queue.size() && this.ws.readyState === this.ws.OPEN) {// 发起请求const params = this.queue.dequeue();this.ws.send(JSON.stringify(params));}requestAnimationFrame(this.loop);}// 接收数据receive(e) {const data = e.data;const uuid = data.uuid;if(uuid) {this.eventEmitter.emit(uuid);}}send(params) {// 发起的请求放到队列中this.queue.enqueue(params);}// 请求request(params, callback) {return new Promise((resolve, reject) => {// 生成uuid,用来匹配发起的ws请求 和 ws响应const uuid = `${new Date().valueOf()}${Math.round(Math.random() * 1000)}`;// 将回调函数放入事件发射器this.eventEmitter.once(uuid, (data) => {// 采用回调函数接收响应数据if(callback) {callback(data);}// resolveresolve(data);});params.uuid = uuid;this.send(params);});}// 关闭websocket连接close() {this.ws.close();}
}

注:本篇未考虑WebSocket创建失败或连接异常的情况。

3. Demo源码
const HTTP = new MockHTTP('http://localhost:8080/ws');
const params = {method: 'add',data: {name: '小明',sex: '男',age: 13}
};HTTP.request(params).then((data) => {console.dir(data);
});

有兴趣的同学,可参考我的博文。

【ECMAScript】自己动手实现ES6的Promise-CSDN博客

【网络协议】WebSocket知识点梳理和总结-CSDN博客

【ECMAScript】基于Map和Set手写一个简单EventEmitter实现事件的发布和订阅-CSDN博客

【数据结构】自己动手使用JavaScript实现栈、队列、双端队列(第一篇)-CSDN博客

注:以上,如有不合理之处,还请帮忙指出,大家一起交流学习~   

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/594502.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

paddle v4 hubserving 部署

环境准备&#xff1a;https://github.com/PaddlePaddle/PaddleOCR/tree/release/2.7/deploy/hubserving#24-%E5%90%AF%E5%8A%A8%E6%9C%8D%E5%8A%A1 服务器启动命令 hub serving start -c deploy/hubserving/ocr_system/config.json客户端请求 python tools/test_hubserving.…

Java ORM 框架 Mybatis详解

&#x1f4d6; 内容 Mybatis 的前身就是 iBatis &#xff0c;是一款优秀的持久层框架&#xff0c;它支持自定义 SQL、存储过程以及高级映射。本文以一个 Mybatis 完整示例为切入点&#xff0c;结合 Mybatis 底层源码分析&#xff0c;图文并茂的讲解 Mybatis 的核心工作机制。 …

面向对象编程(高级)

面向对象编程&#xff08;高级&#xff09; 1、类变量和类方法 &#xff08;1&#xff09; 概念 类变量&#xff0c;也称为静态变量&#xff0c;是指在类级别声明的变量。它们与特定类相关联&#xff0c;而不是与类的实例&#xff08;对象&#xff09;相关联。每个类变量只有…

JavaSE语法之十五:异常(超全!!!)

文章目录 一、异常的概念与体系1. 异常的概念2. 异常的体系结构3. 异常的分类 二、异常的处理方式1. 防御式编程&#xff08;1&#xff09;LBYL 事前防御型&#xff08;2&#xff09;EAFP 时候认错型 2. 异常的抛出3. 异常的捕获&#xff08;1&#xff09;异常声明的 throws&am…

webpack配置入门

webpack是需要一定配置才能使用的&#xff0c;否则无任何效果。在开始webpack学习之前必须理解以下5个核心概念。 5大核心配置 1.entry(入口) webpack从那个文件开始打包&#xff0c;支持单文件入口&#xff08;vue和react脚手架单入口&#xff09;和多文件入口 2.output(输…

工作流入门这篇就够了!

总概 定义&#xff1a;工作流是在计算机支持下业务流程的自动或半自动化&#xff0c;其通过对流程进行描述以及按一定规则执行以完成相应工作。 应用&#xff1a;随着计算机技术的发展以及工业生产、办公自动化等领域的需求不断提升&#xff0c;面向事务审批、材料提交、业务…

OpenCV中实现图像旋转的方法

OpenCV中实现图像旋转的方法 函数&#xff1a;cv2.flip() 功能&#xff1a;水平或者垂直翻转 格式&#xff1a;dst cv2.flip(src,flipCode[,dst]) 参数说明&#xff1a; src&#xff1a;输入图像 dst&#xff1a;和原图像具有相同大小、类型的目标图像。 flipCode&#…

【Hotspot源码】揭秘Java线程创建过程中的各种细节

近期准备给大家分享专题系列文章&#xff0c;聚焦Java多线程机制。会从hotspot源码角度&#xff0c;给大家揭秘平时学习多线程那些从来没有想过的问题&#xff0c;或者存在疑虑却又无法证明的理论。 今天是系列文章首篇&#xff0c;咱们来谈谈Java线程创建的一些细节问题&#…

Vue 中的 ref 与 reactive:让你的应用更具响应性(中)

&#x1f90d; 前端开发工程师&#xff08;主业&#xff09;、技术博主&#xff08;副业&#xff09;、已过CET6 &#x1f368; 阿珊和她的猫_CSDN个人主页 &#x1f560; 牛客高级专题作者、在牛客打造高质量专栏《前端面试必备》 &#x1f35a; 蓝桥云课签约作者、已在蓝桥云…

Lumerical Script------for语句

Lumerical------for语句 正文正文 关于 Lumerical 中 for 语句的用法这里不做过多说明了,仅仅做一个记录,具体用法如下: 通常我们用的比较多的形式是第一种步长值为 1 的情况。对于其他步长值的情况,我们可以使用第二种用法。对于 while 的类似使用方法可以使用第三种。 …

企业级知识图谱的案例分享

近日&#xff0c;在深圳举办的2019中国知识图谱产业发展峰会上&#xff0c;中国人工智能知识图谱联盟&#xff08;AICKI&#xff09;正式发布了《2019知识图谱白皮书》。这份白皮书对中国知识图谱产业的发展现状、趋势和热点进行了解读&#xff0c;并对行业典型应用案例进行了详…

用Audio2Face驱动UE - MetaHuman

新的一年咯&#xff0c;很久没发博客了&#xff0c;就发两篇最近的研究吧。 开始之前说句话&#xff0c;别轻易保存任何内容&#xff0c;尤其是程序员不要轻易Ctrl S 在UE中配置Audio2Face 先检查自身电脑配置看是否满足&#xff0c;按最小配置再带个UE可能会随时崩&#x…

数据结构-线性表-链接存储

关于线性表计顺序存储可看上篇文章&#xff1a;数据结构-线性表-顺序存储-CSDN博客 线性表的链接存储 链接方式存储的线性表简称为链表LinkList&#xff0c;链表的具体存储表示为&#xff1a;用一组任意的存储单元来存放&#xff1b;链表中结点的逻辑次序和物理次序不一定相同…

我的JDK动态代理流程

我的JDK动态代理流程 我梳理的动态代理流程大约是&#xff1a; 如果每一个框架都有自己的BPP&#xff0c;且自己的BPP中都有自己的wrapIfNecessory&#xff0c;那样可能就是一个BPP一个代理类。但通常应该都是各自的框架以提供 Advisior&#xff08;切面&#xff09;的方式&am…

宏晶微 MS9125 USB 投屏控制芯片 VGAHDM输出 全新原装

1.基本介绍 MS9125 是一款 USB 单芯片投屏器,内部集成了 USB2.0 控制器和数据收发模块、视频 DAC、HDMI 接口和音视频处理模块&#xff0c;MS9125 可以通过 USB 接口显示或者扩展 PC、智能手机、平板电脑的显示信息到更大尺寸的显示设备上&#xff0c;支持 VGA 和 HDMI 视频接…

C++中的 greate/less 比较器模板的实现原理及作用

std::greater 是 C 标准库中的一个函数对象&#xff0c;它被设计用来在容器和算法中进行比较&#xff0c;以实现逆序排列或按照 “greater” 的语义进行比较。std::greater 是一个模板类&#xff0c;定义在头文件 <functional> 中。 这个函数对象模板有一个模板参数&…

hcie datacom笔试考多少道题目?

华为认证的HCIE Datacom(数据通信)是网络工程师们向往的顶级认证之一。对于即将参加HCIE Datacom笔试的考生们&#xff0c;你们一定想知道笔试会考多少道题目。下面将为大家揭秘HCIE Datacom笔试的题目数量&#xff0c;并分享一些优秀的培训机构&#xff0c;帮助大家顺利通过考…

diffusers 源码待理解之处

一、训练DreamBooth时&#xff0c;相关代码的细节小计 ** class_labels timesteps 时&#xff0c;模型的前向传播怎么走&#xff1f;待深入去看 ** 利用class_prompt去生成数据&#xff0c;而不是instance_prompt class DreamBoothDataset(Dataset):"""A dat…

JavaSE学习笔记 2023-12-26 --枚举和注释

二十二、枚举和注释 上一篇 个人整理非商业用途&#xff0c;欢迎探讨与指正&#xff01;&#xff01; 文章目录 二十二、枚举和注释22.1枚举22.2注解 22.1枚举 接口/类中的静态属性 以内部类的形式使用较多 public enum Color {RED,GREEN,YELLOW } class Test01 {public s…

循环与基础函数

循环与函数 1.循环的三种方式2.循环的中断与空语句3.函数的定义与使用4.参数的作用域5.指针6.总结 1.循环的三种方式 我们最熟悉的循环为for和while&#xff0c;这两种循环方式在Python系列介绍过。在C中&#xff0c;循环的基本逻辑同Python是类似的。c中while循环的语法如下&…