【问题标题】:Waiting for async function to return true or false - how do I check return value?等待异步函数返回 true 或 false - 如何检查返回值?
【发布时间】:2019-06-13 02:04:44
【问题描述】:

我有一个异步函数songAlreadyInQueue,如果在数据库中找到 ID,它将返回 true,否则返回 false。我想使用这样的功能:

if(!songAlreadyInQueue(ref, id)){
  // do stuff
}

但我知道,因为它是一个异步函数,所以我必须等待结果返回才能真正知道它是真是假。我上面的总是错误的,所以我尝试了这个:

songAlreadyInQueue(ref, id).then((wasFound) => {
                                console.log("wasfound = " + wasFound)
                                if(!wasFound){
                                    //do stuff
                                }
                            })

但这也不起作用。等待这个异步函数完成的正确方法是什么?这就是我的异步函数的样子(简化):

async function songAlreadyInQueue(requestQueueRef, requestID) {
    var querye = requestQueueRef.where("id", "==", requestID)
        .get()
        .then((snap) => {
            snap.docs.forEach(doc => {
                if (doc.exists) {
                    console.log("**************FOUND REQUEST IN QUEUE ALREADY!")
                    return true
                }
            })
            return false
        })
    return querye // not sure if correct. Is this "returning a promise"?
}

【问题讨论】:

  • 您尝试“不起作用”的方式基本上是正确的方式。这种方式到底有什么不妥?
  • “这是“兑现承诺”吗?”是的
  • @JosephSible wasFound 总是假的
  • 那是因为没有考虑forEach回调的返回值
  • @Phil ooooh 所以我为 forEach 回调返回 true 而不是为 songAlreadyInQueue 返回 true?

标签: javascript asynchronous async-await


【解决方案1】:

对于异步函数,您应该使用 await 而不是 then(),这样您就不会创建另一个匿名函数。您是从匿名函数而不是异步函数返回的。试试这个。

async function songAlreadyInQueue(requestQueueRef, requestID) {
  var snap = await requestQueueRef.where("id", "==", requestID).get()
  var found = false;
  snap.docs.forEach(doc => {
    if (doc.exists) {
      console.log("**************FOUND REQUEST IN QUEUE ALREADY!")
      found = true
    }
  })
  return found
}

【讨论】:

  • 使用awaitthen 并不是真正的问题,但您已经指出forEach 的问题
  • 由于docs 是一个普通数组,我建议改用return snap.docs.some(({ exists }) => exists)
  • 使用some 并不是真正的改进,它只是糖和我必须解释的额外内容。一个改进是使用真正的循环并提前返回。也就是说,这绝对是真正的问题,正如我所写的那样,它将修复她在问题中展示的第二个实现。如果我错过了什么,你应该停止神秘并大声说出来。
  • Array.prototype.some() 确实会提前返回(就像您的循环建议一样)。这就是我推荐它的原因
  • 我就是这么想的。您还需要返回承诺。使用异步它无论如何都会返回一个承诺。
猜你喜欢
  • 1970-01-01
  • 2020-08-19
  • 2019-12-17
  • 2020-12-23
  • 1970-01-01
  • 2011-03-04
  • 2020-03-13
  • 2018-01-03
  • 2017-09-24
相关资源
最近更新 更多