【问题标题】:Nested .then in javascript for firebase operation在 javascript 中嵌套 .then 以进行 firebase 操作
【发布时间】:2021-03-02 20:37:35
【问题描述】:

我有两个这样的功能:

export function senderMessageInbox(senderUID, recieverUID, 
    recieverProfileURL, recieverUsername) {
        return new Promise(function(resolve, reject){
            resolve(
                firebase.firestore().collection('messages')
                    .doc(senderUID)
                    .collection("inboxMessages")
                    .doc(recieverUID)
                    .set({
                        date: new Date().getTime(),
                        avatarUrl: recieverProfileURL,
                        message: "",
                        userId: recieverUID,
                        username: recieverUsername 
                })
            )
        })
        
}

export function recieverMessageInbox(senderUID, recieverUID, 
    senderProfileURL, senderUsername) {
        return new Promise(function(resolve, reject){
            resolve(
                firebase.firestore().collection('messages')
                    Same logic as above, but passing diff variables
            )
        })
        
}

我尝试按顺序调用这些,但在导航到另一个屏幕之前需要分别完成它们。我有这样的事情:

function startChat() {
        console.log("senderMessageInbox");
        senderMessageInbox(senderUID, user.uid, user.profileURL, user.username)
        .then(() => {
            console.log("recieverMessageInbox");
            recieverMessageInbox(user.uid, senderUID, currentUser.profileURL, currentUser.username)
        })
        .then(() => {
            console.log("navigation.navigate");
            navigation.navigate('Messages')
        })
    }

我正在记录这些步骤,但似乎这些步骤相互重叠并导致数据库重叠。这是正确的方法吗?我需要这些按顺序完成,然后仅在完成后导航到屏幕。

【问题讨论】:

  • 缩写为firebase logic here的空格中实际上是什么?
  • @m_callens - 使用 firebase 逻辑更新

标签: javascript firebase react-native google-cloud-firestore


【解决方案1】:

这里的问题是导航是异步发生的,调用receiverMessageInbox。如果您需要它们按顺序发生,那么您必须相应地构造 Promise 执行。

function startChat() {
  console.log('senderMessageInbox')
  senderMessageInbox(senderUID, user.uid, user.profileURL, user.username)
    .then(() => {
      console.log('receiverMessageInbox')
      receiverMessageInbox(user.uid, senderUID, currentUser.profileURL, currentUser.username)
        .then(() => {
          console.log('navigation.navigate')
          navigation.navigate('Message')
        })
    })
}

或者,您可以使用async/await 来减少视觉上的混乱:

async function startChat() {
  console.log('senderMessageInbox')
  await senderMessageInbox(senderUID, user.uid, user.profileURL, user.username)

  console.log('receiverMessageInbox')
  await receiverMessageInbox(user.uid, senderUID, currentUser.profileURL, currentUser.username)

  console.log('navigation.navigate')
  await navigation.navigate('Message')
}

【讨论】:

    【解决方案2】:

    您在firebase logic here 处遗漏了一些重要代码,但我假设您正在那里进行某种异步调用。

    在这种情况下,您的 resolve() 语句放错了位置。您的 resolve 只是返回另一个 Promise,这就是 Firebase 调用将返回的内容。

    相反,请在 Firebase 调用返回并且您拥有数据/已完成更新后调用 inside Firebase 调用。

    其次,在您的then 链中,您需要返回 recieverMessageInbox 而不是仅仅调用它。所以:

    return recieverMessageInbox(user.uid, senderUID, currentUser.profileURL, currentUser.username)
    

    根据您添加的代码更新

    外部的Promise 真的没有做任何事情,所以你可以像这样编写你的函数:

    export function senderMessageInbox(senderUID, recieverUID, 
        recieverProfileURL, recieverUsername) {
            return firebase.firestore().collection('messages')
                        .doc(senderUID)
                        .collection("inboxMessages")
                        .doc(recieverUID)
                        .set({
                            date: new Date().getTime(),
                            avatarUrl: recieverProfileURL,
                            message: "",
                            userId: recieverUID,
                            username: recieverUsername 
                    })
    }
    

    并将相同的技术应用于您的其他功能。

    然后,就像我之前说的那样,确保您在链接的 then 语句中返回:

    senderMessageInbox(senderUID, user.uid, user.profileURL, user.username)
            .then(() => {
                console.log("recieverMessageInbox");
                return recieverMessageInbox(user.uid, senderUID, currentUser.profileURL, currentUser.username)
            })
    

    【讨论】:

      猜你喜欢
      • 2023-04-08
      • 2021-07-01
      • 2014-11-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-02-10
      • 1970-01-01
      • 2014-02-23
      相关资源
      最近更新 更多