最近同事要處理 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' }));
參考資料
《AWS CDK 完全學習手冊:打造雲端基礎架構程式碼 IaC》
第 12 屆 iT 邦幫忙鐵人賽 DevOps 組冠的《用 CDK 定 義 AWS 架構》
第 11 屆 iT 邦幫忙鐵人賽《LINE bot 好好玩 30 天玩轉 LINE API》
一個熱愛分享的雲端工程師!