请教一个编程技巧,有没有办法把 websocket 的通讯装到 Promise 里面去? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐关注
Meteor
JSLint - a Javascript code quality tool
jsFiddle
D3.js
WebStorm
推荐书目
Javascript 权威指南第 5 版
Closure: The Definitive Guide
yazoox
V2EX    Javascript

请教一个编程技巧,有没有办法把 websocket 的通讯装到 Promise 里面去?

  •  
  •   yazoox 2020-08-26 22:24:55 +08:00 3484 次点击
    这是一个创建于 1878 天前的主题,其中的信息可能已经有所发展或是发生改变。

    现在有一个需求,要使用 websocket 传输数据,时间大概几秒钟。
    想在传输数据的时候,同时装备下一份数据。准备的时候,也大概几秒钟。

    所以,就在想,能否把这两块并行起来。

    初步想法 /方法,就是用 Promise.all ,但貌似代码不是很好写。
    因为 websocket 的调用,什么 onmessage 等等,不太好放入到 promise 里面去。

    有没有兄弟知道怎么做?或者有其它更好的方法?比如 multi-threads?

    谢谢。

    p.s. Javascript/TypeScript 前端

    16 条回复    2020-08-31 21:25:05 +08:00
    Jirajine
        1
    Jirajine  
       2020-08-26 22:34:18 +08:00 via Android
    jiangzm
        2
    jiangzm  
       2020-08-26 22:51:47 +08:00
    你弄个发送队列不就好了,ws 从队列拿数据发送,组装的数据不断扔到队列。

    后面你要封装 Promise 是要干嘛,没看懂, 可以贴了伪代码示例一下。
    fivge
        3
    fivge  
       2020-08-27 09:03:29 +08:00
    rxjs
    yazoox
        4
    yazoox  
    OP
       2020-08-27 09:42:43 +08:00
    @jiangzm #2 不太好贴。legacy 的项目,一大堆代码全挤在一起。

    基本流程就是先传输文件过去,传输完了,如果成功,再传输证书。即,onmessage 里面,收到成功的回复后,再发送证书。

    但大家知道,申请证书,调用 api 也是需要时间的。
    所以,想在发送文件时,异步调用函数申请证书。等收到文件传输成功消息 /响应后,就能直接发送证书了。
    yazoox
        5
    yazoox  
    OP
       2020-08-27 09:47:36 +08:00
    @jiangzm #2 看懂你的意思了。

    可惜,我们这个逻辑 /流程,当初设计的时候,就有严格的顺序。握手-验证双方身份-发文件-发送证书-……
    有顺序的。相当于“同步”执行。
    azcvcza
        6
    azcvcza  
       2020-08-27 10:02:55 +08:00
    ```
    Onmessage= function(data){
    if(data.type === '某种类型'){
    new Promise(resolve=>{
    resolve(axios.post('xxx'))
    }).then(res=>{
    // get auth
    websocket.send()
    })
    }
    }
    ```
    大致逻辑这样?
    peterjose
        7
    peterjose  
       2020-08-27 10:46:19 +08:00
    没太听懂你在说啥 但是 rxjs-websocket 估计能满足你
    libook
        8
    libook  
       2020-08-27 11:13:16 +08:00
    没有代码,没法提供方案。

    数据量不大到至于爆掉引擎内存空间的话,可以准备两个线程(比如 Web Workers )、一个队列,一个线程持续准备数据并将待发送的数据插入到队列中,另一个线程不断从队列中读取数据发送。如果你用内存存储队列且怕内存爆掉,可以在准备数据的过程里每次循环都检查一下队列大小,如果超出阈值就暂停一段时间。

    Promise 是在一个线程内控制异步 IO 的,Promise.all 不知道你想怎么用,如果单纯吧准备和发送数据的过程扔到里面估计是所有要处理的数据同时准备和发送了,你要是对数据没有先后顺序要求的话也不是不行。Promise 提升效率的关键在于异步 API 异步执行,同步 API 用了 Promise 也不会异步执行,这时候就得考虑多线程了。
    hitaoguo
        9
    hitaoguo  
       2020-08-27 11:24:45 +08:00
    // 把传输文件封装成一个 Promise
    const sendFile = () => Promise.resolve()
    // 申请证书也封装一下
    const requestCert = () => Promise.resolve()
    const sendCert = () => { }
    // 最后通过 Promise.All ,当文件传输好了,并且证书也申请下来了的时候,再发送证书
    Promise.all([sendFile(), requestCert()]).then(sendCert)
    qyvlik
        10
    qyvlik  
       2020-08-27 15:56:49 +08:00
    jiangzm
        11
    jiangzm  
       2020-08-28 00:30:10 +08:00
    @yazoox #4 这很简单啊,异步发送文件和异步请求证书就行,然后在 onmessage 里面同步等待请求证书的结果
    code: https://gist.github.com/jiangzm/4474f2c2f601b23d306235b2233fbe03
    preview: <img src="https://s1.ax1x.com/2020/08/28/d5rJOg.png" alt="d5rJOg.png" border="0" />
    jiangzm
        12
    jiangzm  
       2020-08-28 00:34:50 +08:00
    jiangzm
        13
    jiangzm  
       2020-08-28 00:35:50 +08:00
    yazoox
        14
    yazoox  
    OP
       2020-08-28 15:32:51 +08:00
    @jiangzm
    谢谢。你的这个方法是可以的。
    今天学习到了一招,原来 promise 可以直接 assgin 给一个变量,调用后不管。
    在后面需要的时候,await promise 变量就可以了。
    yazoox
        15
    yazoox  
    OP
       2020-08-31 10:17:47 +08:00
    @jiangzm 这个方法,在使用过程中,还碰到一个问题。就是 try-catch 放在哪里?
    我们并不能保证 requestCert 一定成功,所以,Promise 内部的调用可能需要错误处理, throw exception 。
    错误捕获 /try-catch,是放在 L35 还是 L41 呢?因为 Promise 的启动和检查,分离了。
    jiangzm
        16
    jiangzm  
       2020-08-31 21:25:05 +08:00
    @yazoox #15 有两个改法,一是把 requestCert 里面 fetch 请求的 catch 加上,catch 里面 resolve 空字符串出来即可,还有种方式就是把 async-await 写法改成传统链式调用,即:certPromise.then(res => ws.send(cert)).catch(ex => console.log(ex));

    另外对于不稳定或易超时的接口要加入重试机制
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     2843 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 27ms UTC 08:04 PVG 16:04 LAX 01:04 JFK 04:04
    Do have faith in hat you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86