I have a code however the problem with it is that function getip()
doesn't execute first. I haven't coded in Javascript much so I don't really know what's going on. I want the console.log('connected!')
to execute after the function getip()
has fully completed.
I would appreciate if someone would make the changes required for this to happen with some brief explanation if possible.
(async function getip() {
var responses = [];
var ips = [ "IP1", "IP2" ]
var length = ips.length
for (var i = 0; i < length; i++) {
(async function() {
var ws = new WebSocket('ws://' + ips[i] + ':80');
await new Promise(function(res) {
var timeout = setTimeout(function() {
console.log("Socket connection timeout", ws.readyState);
console.log(ws.url);
if (ws.readyState == 3){
responses.push('connected')
} else {
responses.push('not connected')
}
ws.close();
},5000);
});
})();
}
})();
console.log('connected!')
There are a couple of things happening:
The getip
function is asynchronous, meaning it will not block other code from running while it is executing. This causes the console.log('connected')
to be called because of the asynchronous nature.
Your Promise
doesn't call res
anywhere. That means that the promise will never resolve and therefor, your await
will never stop waiting.
In the setTimeout
in your promise you're looking for the readyState
on the web socket instance. Currently what you're checking is if that state is 3
, which means closed, which it will (probably) not be, because you just opened the web socket. Instead, close the connection and reject the promise, saying that the promise has failed.
Use the onopen
and onerror
events to monitor if the web sockets has successfully opened or when an error occurs. In the onopen
function call resolve
to successfully close the promise. In the onerror
callback reject
the promise and pass some data to it so you can read the error log. In both cases, clear the timeout.
Instead of await
-ing each Promise
, collect all of them in a single array and use either Promise.all()
to await the array of promises. This will ensure that all web sockets are opened in parallel. When everything goes right, the console.log('connected')
will log to the console. Otherwise, if an error was produced by one of the promises, it will log an error.
This topic is quite difficult to grasp and will need some practice to get that click moment.
The example below uses all practices described above. Examine it and feel free to ask any follow-up questions if you have them.
async function getip() {
const ips = ["IP1", "IP2"];
const responses = ips.map(ip => new Promise((resolve, reject) => {
const ws = new WebSocket(`ws://${ip}:80`);
let timeout = setTimeout(() => {
// Save the state before closing, otherwise it will always be the closed state.
const currentState = ws.readyState;
ws.close();
reject({
message: 'Socket connection timeout',
state: currentState
});
}, 5000);
ws.onopen = () => {
clearTimeout(timeout);
resolve(ws);
};
ws.onerror = event => {
clearTimeout(timeout);
reject({
message: 'Socket connection error',
event
});
};
}));
const sockets = await Promise.all(responses);
return sockets;
}
getip().then(sockets => {
console.log('connected!', sockets);
}).catch(error => {
console.log(error);
});
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.