Reputation: 5
I have been working on this problem for a long while, but still can't seem to figure it out. I have a client (or rather a proxy in this case) that should provide a function that returns a userlist. The userlist exists on a server, and should be served on request via socket.io.
Here is what I currently have:
as the client:
async function getUserList(){
return new Promise( (resolve) => {
socket.on('connect', async function (data) {
socket.emit('getData', 'users');
socket.on('data', async function (response) {
var response = await response;
if (response) {
resolve(response);
}
else {
reject(response);
}
});
});
});
};
function getUserList1(){
getUserList().then(function(response){
return response;
}).catch(function(error){console.log(error);})
}
or updated:
getUserList = async function() {
const getUserList1 = () => new Promise(resolve => {
socket.on('connect', data => {
socket.emit('getData', 'users');
socket.on('data', response => {
resolve(response);
});
});
});
console.log('Receiving data');
const users = await getUserList1(); // Waits here until it is done.
console.log('Data received: ', JSON.stringify(users));
return users;
};
var newUsers = getUserList();
console.log(newUsers)
and as the server:
var users = { Foreador: '1234',
mudito: '1234',
troll: '1234',
josocxe: '1234'
};
var subjects = ["Primer tema", "Segundo tema"];
io.on('connection', function(socket){
console.log('a user connected');
socket.on('disconnect', function(){
console.log('user disconnected');
});
socket.on('getData', function(data){
console.log("the request received:", data)
if (data == "users"){
io.emit('data', users);
console.log("sending back users")
}});
socket.on("sendData", function(data){
console.log("the data received:", data)
users = data
console.log("Final users: ", users)
})
});
http.listen(3000, function(){
console.log('listening on *:3000');
});
The code itself works, but if I call getUserList1 I receive first undefined and then later I can log the result. I know that its against the asynchronous nature of JS, but I want to directly receive the result (that is the requirement of the exercise and I dont really see any other way to do it). I have so far tried do achieve this with callbacks as well as promises, but did not succeed. So, does anybody know how I could halt the code execution until I have received the response from the server? I hope I have explained myself and thanks for your help!
Upvotes: 0
Views: 3838
Reputation: 1914
Yeah
First of all, the point of using socket is that you would have a reactive software that can listen to changes.
So, whenever there is a change, you can do something about it.
Look an example:
function initializeSocket() {
const socket = ...;
socket.on('connect', data => {
socket.emit('getData', 'users');
socket.on('data', newUsers =>
renderUsers(newUsers)
);
});
});
}
function renderUsers(users) {
.
. // Here could handle some render logic
.
}
That's the way the event driven architecture works, simple as that.
But, if you need to wait for some async call from the server, I would recommend you to provide an endpoint in your server for it, so you could call it and wait for the response.
Like this simple express example:
app.get('/users', (req, res, next) =>
res.json(users)
)
and on the client side:
const users = await fetch(api_url + '/users')
Upvotes: 1
Reputation: 20954
What you need is to use async
/ await
to store your result in a variable. You are already doing it in some parts of your code so you are familiar. You could use an async IIFE to make your current scope able to use the await
keyword.
Below I've made an example with a simplified version of your getUserList
function and a single variable which calls the value with the await
keyword. This will halt the execution of the rest of the function scope until getUserLists
resolves. Now you can use the result from the getUserList
function in the user
variable.
(async function() {
const getUserList = () => new Promise(resolve => {
socket.on('connect', data => {
socket.emit('getData', 'users');
socket.on('data', response => {
resolve(response);
});
});
});
const users = await getUserList(); // Waits here until it is done.
// Continue all your code after this.
}());
Upvotes: 0