【问题标题】:Running concurrent firebase requests using promises使用 Promise 运行并发 firebase 请求
【发布时间】:2018-12-03 05:15:58
【问题描述】:

我正在尝试使用 Promise.all() 同时执行多个 Firebase 云存储查询:

exports.onNewOrder = 
functions.database.ref('/orders/{orderId}').onCreate(event => {  
    const data = event.val();
    const orderedBy = data.ordered_by;
    const creations = data.creations;

    var promises = []
    for (var entry of creations.entries()) {
        var key = entry[0], value = entry[1];
        var creationPromise = admin.database().ref("creations/"+ key);
        creationPromise.once("value")
        .then((crSnapshot)=>{
            const crName = crSnapshot.val().name;
            const created = crSnapshot.val().created;
            return "crName+'\n'+created”;
        }).catch((error) => {
            console.log("creation details error : "+ error);
        });
        promises.push(creationPromise);
    }

    const userPromise = admin.database().ref("users/"+ orderedBy);
    userPromise.once("value")
    .then((snapshot) => {
        var name = snapshot.val().name;
        var email = snapshot.val().email;
        const userDetails = name+'\n'+email;
        return userDetails; 
    }).catch((error) => {
        console.log("user details error :"+ error);
    });

    promises.push(userPromise);

    return Promise.all(promises).then(results => {
        console.log("results: " + results)
        return true;
    }).catch((error) => {
        console.log("sendMail failed : "+ error);
    });
});

我希望看到每个已执行承诺的完整查询结果,但是我得到的是以下内容:

结果:

https://....firebaseio.com/creations/cr_1bfd5f16212f44c792a2cbe3e9c6e4cc
https://....firebaseio.com/creations/cr_343c363c2a214487ba8cb7101653f6af
https://....firebaseio.com/creations/cr_e3f7a0bafd1542ac898d96e86155b94e
https://....firebaseio.com/users/us_5e4c28e18e63454c861caa5c4fe6a6f0

我错过了什么吗?

【问题讨论】:

  • 顺便说一句,您的所有问题都没有被标记为已回答。接受答案并投票是我们必须鼓励其他用户在 SO 上帮助我们的少数几种方法之一;也使其他用户更容易找到有用的帖子。如果您对答案没有任何兴趣,为什么会有人抽出时间来写它们?
  • 好点。如何将问题标记为已回答?

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


【解决方案1】:

以下应该可以解决问题。

详细here

Promise.all(iterable) 方法返回一个 Promise 当 iterable 参数中的所有承诺都具有 已解决或当 iterable 参数不包含任何承诺时。它 以第一个拒绝的承诺的原因拒绝。

因此,您需要在promises 数组中添加一些承诺。

once() 方法确实返回了一个承诺,正如文档中的 here 所解释的那样。

exports.onNewOrder = 
functions.database.ref('/orders/{orderId}').onCreate(event => {  
    const data = event.val();
    const orderedBy = data.ordered_by;
    const creations = data.creations;

    const promises = []

    for (var entry of creations.entries()) {
        var key = entry[0];
        var creationPromise = admin.database().ref("creations/"+ key).once("value");
        promises.push(creationPromise);
    }

    const userPromise = admin.database().ref("users/"+ orderedBy).once("value");
    promises.push(userPromise);

    return Promise.all(promises)
    .then(results => {
        console.log("results: " + results);
        return true;
        //actually here you will probably do something else than just write the results to the console. 
        //In this case you should return a promise (instead of true).
    }).catch((error) => {
        console.log("sendMail failed : "+ error);
        return false;
    });

});

【讨论】:

  • 谢谢,promise 现在似乎在起作用,尽管控制台显示 results: [object Object]。我还缺少什么吗?
  • 来自Promise.all(promises) 的结果通常是一个包含所有承诺结果的数组,与您在promises 数组中推送承诺的顺序相同。所以肯定有问题,但如果没有更多细节,很难确切地知道原因。
  • 我忘了感谢您的最后评论。非常感谢!它有帮助: return Promise.all(promises) .then(results => { results.forEach(element => { ... }); return sendMail(orderid, text); }).catch((error) => { console. log("发送邮件失败:"+错误); });
  • 很高兴能帮到你!您可以通过单击答案左侧的灰色复选标记来接受我的答案。谢谢
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-06-29
  • 2019-08-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-08-06
相关资源
最近更新 更多