[英]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.