首页 > 解决方案 > Firebase 通过 Promises 返回的多个异步请求

问题描述

我有一个 Firebase 函数,它试图获取一组 UID 并返回一组用户对象。我试图用来Promise.all()返回所有异步结果,但我得到一个空数组返回。但是,我在事后得到了注销的结果。

const fetchUserObjects = function(uids){
  let promises = []
  uids.forEach((uid) => {
    admin.database().ref(`/users/${uid}`).once("value")
    .then(function(dataSnapshot) {
      const userDataAll = dataSnapshot.val()
      const userData = {}
      userData.id = userDataAll.id
      userData.username = userDataAll.username
      userData.first = userDataAll.first
      userData.last = userDataAll.last

      promises.push(userData)
      console.log(userData)
    })
    .catch((error) => {
      // Re-throwing the error as an HttpsError so that the client gets the error details.
      throw new functions.https.HttpsError('unknown', error.message, error);
    });
  })

  return Promise.all(promises);

}

return fetchUserObjects(uids)

标签: javascriptfirebasefirebase-realtime-databasees6-promise

解决方案


fetchUserObjects总是返回一个空数组。once()在将值推送到数组之前,没有什么可以确保开始的异步工作是完整的。另请注意,您实际上并没有将承诺推入该数组。您正在推送普通的旧 JavaScript 对象。您需要将实际的 Promise 推送到数组中,并且您需要这样做而不必等待其他 Promise 解决。相反,它应该是这样的:

const fetchUserObjects = function(uids){
  let promises = []
  uids.forEach((uid) => {
    const promise = admin.database().ref(`/users/${uid}`).once("value")
    .then(function(dataSnapshot) {
      const userDataAll = dataSnapshot.val()
      const userData = {}
      userData.id = userDataAll.id
      userData.username = userDataAll.username
      userData.first = userDataAll.first
      userData.last = userDataAll.last

      console.log(userData)
      return userData
    })
    .catch((error) => {
      // Re-throwing the error as an HttpsError so that the client gets the error details.
      throw new functions.https.HttpsError('unknown', error.message, error);
    });

    promises.push(promise)

  })

  return Promise.all(promises);

}

请注意,promise 会立即推送到 promises 数组中,并且它将使用回调userData返回的对象进行解析。then


推荐阅读