Асинхронная функция возвращает неопределенный - PullRequest
0 голосов
/ 12 февраля 2019

Мне действительно нужно освежить свои асинхронные ожидания и обещания.Я хотел бы получить несколько советов.

Я выполняю асинхронный вызов функции для пожарного магазина Firebase.Функция должна возвращать строку в зависимости от одного входного параметра.

Эта функция предназначена для чата 1-1 пользователя.Функция состоит в том, чтобы создать чат / найти существующий чат и вернуть его идентификатор.

Прямо сейчас я получаю undefined в качестве возвращаемого значения openChat и не могу понять, почему.В противном случае функция работает, кроме возврата.

У меня две функции.Один из них - метод жизненного цикла компонента класса React, другой - моя асинхронная функция firebase.

Вот метод жизненного цикла компонента класса:

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

, а вот асинхронная функция:



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

Если у вас есть какие-либо полезные советы, я бывсегда рад их услышать!

Ожидаемые результаты - возвращаемая строка.Строка правильно отображает console.log асинхронной функции).

Фактические результаты состоят в том, что возвращаемое значение асинхронной функции не определено.

Ответы [ 2 ]

0 голосов
/ 12 февраля 2019

Вы должны await результаты ваших вызовов в пожарном депо, если вы хотите вернуть их значения, вы уже используете 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   
    }
}

Вы также должны напрямую ожидать вызовов к функции:

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
}
0 голосов
/ 12 февраля 2019

Вы ничего не возвращаете из своей функции openChat, поэтому функция разрешается в undefined.

Вам нужно написать:

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()
    /* .... */
}

И эти new Promise вgetChatId и requestChat не имеют особого смысла.Достаточно дождаться результата 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
}
...