簡體   English   中英

改進從 Promise 內的 WebSocket 的 onmessage 事件獲取結果

[英]Improve getting result from onmessage event from WebSocket inside Promise

我有一個 WebSocket 客戶端發送消息並隨后接收響應。 我希望能夠在任何地方調用它並將響應存儲回來,如下所示:

    // Global var
    var response

    // Connection to WS
    connect = () => {
        return new Promise(function(resolve, reject) {
            var server = new WebSocket('ws://localhost:8443/test/');
            server.onopen = function() {
                resolve(server);
            };
            server.onerror = function(err) {
                console.log(err)
                reject(err);
            };

        });
    }

    // Send request and receive message back
    async request(data){
        var request = {
            id: "test",
            data: data
        }

        connect().then((server) => {          

            server.send(JSON.stringify(request))

            server.onmessage = ({data}) => {
                response = JSON.parse(data) // save result
            }

        })
        .catch(function(err) {
            console.log(err)
        });
    }

    // Make request
    await request("test")
    
    // Access response
    console.log(response) // prints undefined

最后響應仍然是未定義的,因為當它到達console.log(response)時,還沒有從異步調用中更新。

我能想到的唯一解決方案是添加這樣的延遲:

    delay(){
        var promise = new Promise(function(resolve) {
            window.setTimeout(function() {
              resolve('done!');
            }, 10);
          });
          return promise;
    }

    // Make request
    await request("test")

    // Await for delay 
    await delay();
    
    // Access response
    console.log(response) // prints data received!

這是正確的方法嗎? 增加 10ms 的延遲就足以讓它更新似乎很奇怪。 如果您有比我添加的延遲更好的解決方案,請告訴我。

您的connect()調用在它前面缺少await 最重要的是,您永遠不會告訴您的 promise 等待響應本身。 這是一個快速修復。

await connect().then((server) => {          

  server.send(JSON.stringify(request))

  return new Promise((resolve, reject) => {
    server.onmessage = ({data}) => {
      response = JSON.parse(data) // save result
      resolve()
    }
  })
})

從技術上講,您可以將await交換為return ,因為這是您的結束語句,並且您已將await放在您的request調用中。

return connect().then((server) => {          

  server.send(JSON.stringify(request))

  return new Promise((resolve, reject) => {
    server.onmessage = ({data}) => {
      response = JSON.parse(data) // save result
      resolve()
    }
  })
})

盡管它有效,但我鼓勵您重構連接初始化過程 - 絕對沒有理由在每次請求嘗試時重新連接到 WS,除非您在完成時實際上與它斷開連接。

https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Asynchronous/Async_await

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM