Reputation: 51
I understand node js is async and i've looked many resources to fix this with no success. my problem is, i have this mongodb query i'm executing, but my function returns before the query finishes i know about promises and i'm using them but it doesn't seem to work, what am i doing wrong. my code can be found below:
function findConversation(Id){
return new Promise(function(resolve, reject){
ConversationSchema.find({ 'participants.Id': Id }, function (err, conversations) {
if (err) return reject(err);
if (conversations) {
console.log("Conversation JSON: " + conversations)
}
resolve(conversations)
})
})
}
this is the query that i'm executing, but it's called in the bellow function:
function getConversations(user){
var newConversations = []
query.findConversation(user.userName).then(function(convers) {
if(convers) {
console.log("conversation was found: " + convers)
newConversations = convers
}
else {
console.log("conversation was not found: " + convers)
}
}).catch(function(reason) {
console.log("failure when finding conversation: " + reason)
})
return newConversations
}
now the above function is the one that returns without waiting for the promise, bellow i call this function:
socket.on(VERIFY_USER, (nickname, callback)=>{
query.userExist(nickname).then(function(user){
if(user){
console.log("user exist")
var conversation = factories.getConversations(user)
console.log("Existing user Conversations: " + conversation)
callback({ userExist:true, user:factories.getUser(user, socket.id), conversations: conversation})
}
else {
console.log("user does not exist")
callback({ userExist:false, user:factories.createUser(nickname, socket.id), conversations:[]})
}
}).catch(function(reason) {
console.error(reason);
})
})
Upvotes: 2
Views: 3697
Reputation: 901
Remember that when using promises you have to use them throughout your code. Anything that requires an asynchronous function in order to return correctly also has to be asynchronous. I think you do understand that query
doesn't complete before getConversations
does, and that getConversations
will not wait for query to complete.
So here getConversations
has to be structured just like findConversation
with a new Promise and calling resolve(newConversations)
. You would then use .then
just as you did before when you call it.
factories.getConversations(user).then((conversation) => {
console.log("Existing user Conversations: " + conversation);
callback({userExist: true, user: factories.getUser(user, socket.id), conversations: conversation});
});
If you find using promises too difficult or messy and you are able to use ES6 you should probably use async/await. This will allow you to write code as if it were synchronous yet still being non-blocking in reality. If getConversations were an asynchronous function, for example, you would then be able to use it very simply:
let conversation = await factories.getConversations(user);
console.log("Existing user Conversations: " + conversation);
callback({userExist: true, user: factories.getUser(user, socket.id), conversations: conversation});
Overall you should review how promises work or really try to learn how async/await works.
Edit: Related question
Upvotes: 1