1.前言
为什么会将websocket
和promise
所联系起来呢?
因为websocket
不像http请求
一样,发送的请求不会得到对应的回复,这样就会导致如果通过websocket
发送消息之后,就无法对此消息进行追溯,使用起来非常不方便,并且很多功能无法实现,与客户端/服务端协调好数据个时候,就可以通过promise
获取到消息的回执结果了
如何结合起来?
大致就是websocket
的两端(客户端,服务端),提前确定好websocket
消息的格式,进行协调,需要注意有个关键点,就是每个消息都会有一个唯一标识(uuid
),发送到服务端的消息的状态以及promise
的成功与失败,都需要根据这个唯一标识进行处理
2.步骤拆分
- 首先创建一个自定义的
websocket
的消息发送的方法
const send = (param) => {}
- 在每个发送到服务端消息中都添加一个
uuid
,用于标识当前消息
const send = (param) => {const data = {uuid:... // uuid...param}
}
- 发送消息的方法返回一个
promise
,得到promise
的resolve
与reject
方法
const send = (param) => {return new Promise((resolve,reject)=>{const data = {uuid:... // uuid...param}})
}
- 创建一个空对象,对象中保存
promise
的resolve
与reject
方法(这里可以自定义websocket
消息超时的处理逻辑,可自行拓展)
const send = (param) => {return new Promise((resolve,reject)=>{const data = {uuid:... // uuid...param}const promiseData = {resolve,reject}})
}
- 将此对象添加到一个
Map
解构,其中的key
就是唯一标识,value
就是上方创建的对象,这样的话,每个消息都会有一个单独的对象,可以控制此消息的成功,失败,超时等等处理
const receiverMap = new Map()
const send = (param) => {return new Promise((resolve,reject)=>{const data = {uuid:... // uuid...param}const promiseData = {resolve,reject}receiverMap.set(data.uuid, promiseData)})
}
- 然后将
websocket
消息发送出去(需要保证在这些操作之前websocket
已经连接了)
const receiverMap = new Map()
const send = (param) => {return new Promise((resolve,reject)=>{const data = {uuid:... // uuid...param}const promiseData = {resolve,reject}receiverMap.set(data.uuid, promiseData)webscoket.send(data)})
}
- 服务端接收到客户端发送的
websocket
消息之后,将唯一标识(uuid
)提取出来,然后执行对应操作 - 对应操作执行成功或失败后按照与客户端协定好的格式返回给客户端,例如定义一个
status
字段,0表示成功,1表示执行失败,需要注意,这里的uuid
也需要返回给客户端,客户端需要获取消息对应的请求是什么 - 客户端接收到请求后,将
status
,uuid
字段解构出来,此时就可以通过uuid
从Map
解构中获取到对应的promise
的resolve
与reject
方法了,此时再根据status
的状态决定调用resolve
还是reject
即可
webscoket.addEventListener('message', (data)=>{// 解析messageData的内容const { uuid, status,param } = data// 获取当前接受到的消息所对应的websocket消息对象const msgRectiver = receiverMap.get(uuid)if(status === 0){msgRectiver.resolve(param)} else {msgRectiver.reject(param)}})
- 注意,请求收到后,无论失败还是成功,都需要将
Map
解构中当前的uuid
删除掉,避免大量数据不清楚导致的Map
解构过大
webscoket.addEventListener('message', (data)=>{// 解析messageData的内容const { uuid, status,param } = data// 获取当前接受到的消息所对应的websocket消息对象const msgRectiver = receiverMap.get(uuid)if(status === 0){msgRectiver.resolve(param)} else {msgRectiver.reject(param)}// 从Map中删除对应的消息receiverMap.delete(uuid)})
3.整体代码
const receiverMap = new Map()
const send = (param) => {return new Promise((resolve,reject)=>{const data = {uuid:... // uuid...param}const promiseData = {resolve,reject}receiverMap.set(data.uuid, promiseData)webscoket.send(data)})
}webscoket.addEventListener('message', (data)=>{// 解析messageData的内容const { uuid, status,param } = data// 获取当前接受到的消息所对应的websocket消息对象const msgRectiver = receiverMap.get(uuid)if(status === 0){msgRectiver.resolve(param)} else {msgRectiver.reject(param)}// 从Map中删除对应的消息receiverMap.delete(uuid)})
4.补充以及总结
这里只是大致实现了websocket
与promise
结合后的效果,内部可以进行很多其他的自定义操作,例如超时判断,消息警告,消息正在处理中,等等。
可以根据自己的需求进行调整,通过这里的方法,就可以对websocket
消息进行追踪了,并且使用体验也比较好,可以直接使用.then
,.catch
等方法直接监听本次消息是否执行成功,以及获取到执行过程中服务端返回的一些数据!
到这里,本篇文章内容已经全部结束了,如果有什么其他的想法或者好的建议,欢迎大家私信或评论😁