Broulaye Doumbia
Broulaye Doumbia

Reputation: 51

how to make code wait for function return in node js

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);
    })
	})
this always returns Existing user Conversations:

Upvotes: 2

Views: 3697

Answers (1)

Froast
Froast

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

Related Questions