WebSocket 等待連線完成後發送指令

最近同事要處理 WebSocket 連線不過因為 js 是非同步機制,在沒有 async 與 await 的情況會因為還沒連線成功就發送訊息而失敗,所以今天的目標是要確保 WebSocket 連線成功後才發送訊息,我們先來看看有問題的 Code。

非同步的情況

如下可以看到我們只有在 client.on 綁定 message 與 open,在最後使用 client.send(JSON.stringify({ data: ‘data’ })); 發送 WebSocket 其實就會發生錯誤,因為連線根本還沒成功,我們應該要等到 console.log(‘open’) 執行完成才可以發送訊息。

那我們是否可以直接把 client.send 放到 open 的 event 裡面呢?答案是可以的,不過這樣在不熟悉 js 的人可能會比較不能理解,那我們可以有其他的解法嗎?

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

client.on('message', msg => console.log(msg));

client.on('open', event => console.log('open'));

client.send(JSON.stringify({ data: 'data' }));

使用 await 同步的情況

其實我們可以巧妙的配合 await 與 promise 讓非同步的 js ,完成連線前都會停在等待的地方,如下可以看到如何實作的,我們使用 Promise 把 open 的 event 包起來,在它發生的時候才回傳達成同步流程!

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

client.on('message', msg => console.log(msg));

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

client.send(JSON.stringify({ data: 'data' }));

參考資料