【问题标题】:How do I avoid promise nesting in this case with Firebase Cloud Functions?在这种情况下,如何使用 Firebase Cloud Functions 避免承诺嵌套?
【发布时间】:2019-07-22 08:14:40
【问题描述】:

我有一个 Android 应用,可以将电话号码列表发送到我项目中的云函数。然后,服务器应该检索用户所有电话号码的列表,获取两个数组之间的交集(相同元素),然后将交集数组中用户的 Firebase Auth 用户 ID 发送回应用程序。

这是我想出的:-

// The Cloud Functions for Firebase SDK to create Cloud Functions and setup triggers.
const functions = require('firebase-functions');

// The Firebase Admin SDK to access the Firebase Realtime Database.
const admin = require('firebase-admin');
admin.initializeApp();

const auth = admin.auth();
const _ = require('underscore');

exports.getUids = functions.https.onCall((data, context) => {
    return auth.listUsers().then(userRecords => {
        var allPhoneNumbers = [];
        userRecords.users.forEach(user => allPhoneNumbers.push(user.phoneNumber));
        var phoneNumbers = _.intersection(allPhoneNumbers, data);
        var Uids = [];
        //the next line is where I am nesting promises
        phoneNumbers.forEach(phoneNumber => auth.getUserByPhoneNumber(phoneNumber).then(user => Uids.push(user.uid)));
        return Uids;
    }).catch(error => console.error(error));
});

我从未使用过 JavaScript 编程,但我正在尝试。现在已经2天了,我只是不知道如何解决这个问题。我已经尝试了至少 10 种不同的方法。我发现承诺真的很难处理。任何帮助表示赞赏。

【问题讨论】:

  • @paradox 我尝试使用 async/await 但我无法理解一般的 JS 语法。我需要一些额外的帮助:(。我很快就会在这里发布我的 async/await 方法,这样你们就可以告诉我我做错了什么。
  • 嵌套没问题,问题在于使用forEach
  • @Bergi 我现在知道了,我认为嵌套是问题所在,因为编译器会发出警告。

标签: javascript node.js firebase promise google-cloud-functions


【解决方案1】:

您可以使用Promise.all 来避免此问题。请注意,对getUserByPhoneNumber 的调用不会等待完成。你必须连锁承诺等待它。这是一个带有常规 Promise 的实现:

return auth
  .listUsers()
  .then(userRecords => {
    var allPhoneNumbers = [];
    userRecords.users.forEach(user => allPhoneNumbers.push(user.phoneNumber));
    var phoneNumbers = _.intersection(allPhoneNumbers, data);

    return Promise.all(
      phoneNumbers.map(phoneNumber => auth.getUserByPhoneNumber(phoneNumber))
    );
  })
  .then(users => {
    return users.map(user => user.uid);
  })
  .catch(error => {
    console.error(error);
  });

这是一个使用 async/await 的实现:

return auth
  .listUsers()
  .then(async userRecords => {
    var allPhoneNumbers = [];
    userRecords.users.forEach(user => allPhoneNumbers.push(user.phoneNumber));
    var phoneNumbers = _.intersection(allPhoneNumbers, data);

    const users = await Promise.all(
      phoneNumbers.map(phoneNumber => auth.getUserByPhoneNumber(phoneNumber))
    );

    return users.map(user => user.uid);
  })
  .catch(error => {
    console.error(error);
  });

【讨论】:

  • 非常感谢!正如我从Promise.all 的所有文档中了解的那样,它会等到其中的所有承诺返回,然后将它们的结果存储在一个数组中?稍后我会测试代码并标记为正确。
  • 代码完美运行,已被标记为解决方案。
  • 是的,就是这样:它需要一组 Promise 等到它们都成功并在数组中返回它们的结果。
猜你喜欢
  • 2020-04-22
  • 2019-05-22
  • 2019-03-04
  • 2011-01-09
相关资源
最近更新 更多