简体   繁体   English

异步函数返回未定义

[英]Async function is returning undefined

I really need to brush up on my async await and promises.我真的需要重温我的异步等待和承诺。 I would love some advice.我希望得到一些建议。

I'm making an async function call to firebase firestore.我正在对 firebase firestore 进行异步函数调用。 The function should return a string depending on a single input param.该函数应根据单个输入参数返回一个字符串。

The feature is for a 1-1 user chat.该功能用于 1-1 用户聊天。 The function is to create the chat/find existing chat, and return its ID.该功能是创建聊天/查找现有聊天,并返回其ID。

Right now, I am getting undefined as the return value of openChat and can't work out why.现在,我得到undefined作为openChat的返回值,并且不知道为什么。 The function otherwise works, apart from the return.除了返回之外,该函数还可以正常工作。

I have two functions.我有两个功能。 One is a React class component lifecycle method, the other my firebase async function.一个是 React 类组件生命周期方法,另一个是我的 firebase 异步函数。

Here is the class component lifecycle method:这是类组件生命周期方法:

async getChatId(userId) {
  let chatPromise = new Promise((resolve, reject) => {
    resolve(openChat(userId))
  })
  let chatId = await chatPromise
  console.log('chatId', chatId) //UNDEFINED
  return chatId
}

async requestChat(userId) {
  let getAChat = new Promise((resolve, reject) => {
    resolve(this.getChatId(userId))
  })
  let result = await getAChat
  console.log('result', result) //UNDEFINED
}

render() {
  return (<button onClick = {() => this.requestChat(userId)}>get id</button>)
}

and here is the async function:这是异步函数:

// both my console.log calls show correctly in console
// indicating that the return value is correct (?)

export async function openChat(otherPersonId) {
  const user = firebase.auth().currentUser
  const userId = user.uid

  firestore
    .collection('users')
    .doc(userId)
    .get()
    .then(doc => {
      let chatsArr = doc.data().chats

      let existsArr =
        chatsArr &&
        chatsArr.filter(chat => {
          return chat.otherPersonId === otherPersonId
        })
      if (existsArr && existsArr.length >= 1) {
        const theId = existsArr[0].chatId

        //update the date, then return id

        return firestore
          .collection('chats')
          .doc(theId)
          .update({
            date: Date.now(),
          })
          .then(() => {
            console.log('existing chat returned', theId)
            //we're done, we just need the chat id
            return theId
          })
      } else {
        //no chat, create one

        //add new chat to chats collection
        return firestore
          .collection('chats')
          .add({
            userIds: {
              [userId]: true,
              [otherPersonId]: true
            },
            date: Date.now(),
          })
          .then(docRef => {
            //add new chat to my user document

            const chatInfoMine = {
              chatId: docRef.id,
              otherPersonId: otherPersonId,
            }
            //add chat info to my user doc
            firestore
              .collection('users')
              .doc(userId)
              .update({
                chats: firebase.firestore.FieldValue.arrayUnion(chatInfoMine),
              })

            //add new chat to other chat user document
            const chatInfoOther = {
              chatId: docRef.id,
              otherPersonId: userId,
            }
            firestore
              .collection('users')
              .doc(otherPersonId)
              .update({
                chats: firebase.firestore.FieldValue.arrayUnion(chatInfoOther),
              })
            console.log('final return new chat id', docRef.id)
            return docRef.id
          })
      }
    })
}

If you have any useful tips whatsoever, I would be forever grateful to hear them!如果您有任何有用的提示,我将永远感激听到他们!

Expected results are a returned string.预期结果是返回的字符串。 The string is correctly displayed the console.log of the async function).该字符串正确显示在异步函数的 console.log 中)。

Actual results are that the return value of the async function is undefined.实际结果是 async 函数的返回值未定义。

You do not return anything from your openChat function, so that function resolves to undefined .您不会从openChat函数返回任何内容,因此该函数解析为undefined

You have to write:你必须写:

export async function openChat(otherPersonId) {
  const user = firebase.auth().currentUser
  const userId = user.uid

  return firestore // here you need to return the returned promise of the promise chain
    .collection('users')
    .doc(userId)
    .get()
    /* .... */
}

And those new Promise in getChatId and requestChat do not make much sense.getChatIdrequestChat那些new Promise没有多大意义。 It is sufficient to await the result of openChat(userId) or this.getChatId(userId)就足够了等待的结果openChat(userId)this.getChatId(userId)

async getChatId(userId) {
  let chatId = await openChat(userId)
  console.log('chatId', chatId) //UNDEFINED
  return chatId
}

async requestChat(userId) {
  let result = await this.getChatId(userId)
  console.log('result', result) //UNDEFINED
}

You should await the results from your firestore calls if you want to return their values, you are already using async functions :如果您想返回它们的值,您应该await Firestore 调用的结果,您已经在使用async函数:

export async function openChat(otherPersonId) {
    const user = firebase.auth().currentUser
    const userId = user.uid

    const doc = await firestore
        .collection('users')
        .doc(userId)
        .get()

    let chatsArr = doc.data().chats

    let existsArr =
        chatsArr &&
        chatsArr.filter(chat => chat.otherPersonId === otherPersonId)
    if (existsArr && existsArr.length >= 1) {
        const theId = existsArr[0].chatId

        //update the date, then return id

        await firestore
            .collection('chats')
            .doc(theId)
            .update({
                date: Date.now(),
            })

        return theId
    } else {

        const docRef = await firestore
            .collection('chats')
            .add({
                userIds: { [userId]: true, [otherPersonId]: true },
                date: Date.now(),
            })

        const chatInfoMine = {
            chatId: docRef.id,
            otherPersonId: otherPersonId,
        }
        //add chat info to my user doc
        firestore
            .collection('users')
            .doc(userId)
            .update({
                chats: firebase.firestore.FieldValue.arrayUnion(chatInfoMine),
            })

        //add new chat to other chat user document
        const chatInfoOther = {
            chatId: docRef.id,
            otherPersonId: userId,
        }
        firestore
            .collection('users')
            .doc(otherPersonId)
            .update({
                chats: firebase.firestore.FieldValue.arrayUnion(chatInfoOther),
            })
        console.log('final return new chat id', docRef.id)
        return docRef.id   
    }
}

You should also directly await your calls to the function :您还应该直接等待对函数的调用:

async getChatId(userId) {
    let chatId = await openChat(userId)
    console.log('chatId', chatId) //UNDEFINED
    return chatId
}

async requestChat(userId) {
  let result = await this.getChatId(userId)
  console.log('result', result) //UNDEFINED
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM