【问题标题】:how to make code wait for function return in node js如何使代码等待节点js中的函数返回
【发布时间】:2018-06-06 23:45:48
【问题描述】:

我知道 node js 是异步的,我查看了很多资源来解决这个问题,但没有成功。我的问题是,我正在执行这个 mongodb 查询,但是我的函数在查询完成之前返回,我知道 Promise 并且我正在使用它们,但它似乎不起作用,我做错了什么。我的代码可以在下面找到:

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)
    })
	})
}

这是我正在执行的查询,但它在下面的函数中被调用:

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
}

现在上面的函数是不等待承诺就返回的函数,下面我调用这个函数:

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);
    })
	})
这总是返回 现有用户对话:

【问题讨论】:

  • 是的,我也一直在与同样的问题作斗争......因为承诺不会等待查询的返回

标签: javascript node.js mongodb socket.io async-await


【解决方案1】:

请记住,在使用 Promise 时,您必须在整个代码中使用它们。任何需要异步函数才能正确返回的东西也必须是异步的。我想你确实明白query 不会在getConversations 之前完成,而且getConversations 不会等待查询完成。

所以这里getConversations 的结构必须像findConversation 一样,带有一个新的Promise 并调用resolve(newConversations)。然后,您将使用 .then,就像您之前调用它时所做的那样。

factories.getConversations(user).then((conversation) => {
    console.log("Existing user Conversations: " + conversation);
    callback({userExist: true, user: factories.getUser(user, socket.id), conversations: conversation});
});

如果你发现使用 Promise 太难或太杂乱并且你能够使用 ES6,你可能应该使用async/await。这将允许您编写代码,就好像它是同步的但实际上仍然是非阻塞的。例如,如果 getConversations 是一个异步函数,那么您就可以非常简单地使用它:

let conversation = await factories.getConversations(user);
console.log("Existing user Conversations: " + conversation);
callback({userExist: true, user: factories.getUser(user, socket.id), conversations: conversation});

总体而言,您应该查看 Promise 的工作原理,或者真正尝试了解 async/await 的工作原理。

编辑:Related question

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-05-22
    • 2017-01-24
    • 2021-07-24
    • 2018-10-06
    • 2020-11-06
    • 1970-01-01
    • 2020-08-12
    • 2021-04-24
    相关资源
    最近更新 更多