【问题标题】:How to ensure that all operations in a cloud function have been successfully completed?如何确保云功能中的所有操作都已成功完成?
【发布时间】:2019-02-14 01:13:39
【问题描述】:

我正在使用 Firebase Cloud Functions,它通过在 Firestore 中创建文档来触发。在创建对象时,我需要并行执行两个不同的操作:

  1. 更新特定文档中的字段值(不是创建并触发云功能的文档)
  2. 在另一个文档上运行事务

所以我的问题是:

  1. 如何确保我的两个操作都在结束云功能本身之前成功完成
  2. 如何为这两个操作中的每一个实现单独的重试机制(因为我不希望整个函数有一个共同的重试机制,因为它可以重做事务操作,即使它是另一个操作失败)?

这是我当前的代码:

exports.onCityCreated = functions.firestore
    .document('Cities/{cityId}')
    .onCreate((snap, context) => {
        const db = admin.firestore(); 
        const newCity = snap.data();
        const mayorId = newEvent.mayorID;
        const mayorRef = db.doc('Users/'+ mayorId);

        const timestamp = admin.firestore.FieldValue.serverTimestamp();
        db.doc('Utils/lastPost').update({timestamp: timestamp});    //First Operation - Timestamp Update

        return db.runTransaction(t => {    //Second Operation - Transaction
                return t.get(mayorRef).then(snapshot => {
                    var new_budget = snapshot.data().b - 100;
                    return t.update(mayorRef, {b: new_budget});
                })
            .then(result => {
                return console.log('Transaction success!');
            })
            .catch(err => {
                console.log('Transaction failure:', err);
            });
        });
});

【问题讨论】:

    标签: javascript firebase asynchronous google-cloud-firestore google-cloud-functions


    【解决方案1】:

    当你有多个这样的操作时,解决方案是使用Promise.all()。这需要一组 Promise,然后返回一个 Promise,当您传入的所有 Promise 都已解析时,该 Promise 会解析。

    exports.onCityCreated = functions.firestore
        .document('Cities/{cityId}')
        .onCreate((snap, context) => {
            const db = admin.firestore(); 
            const newCity = snap.data();
            const mayorId = newEvent.mayorID;
            const mayorRef = db.doc('Users/'+ mayorId);
    
            const timestamp = admin.firestore.FieldValue.serverTimestamp();
            var p1 = db.doc('Utils/lastPost').update({timestamp: timestamp});
    
            var p1 = db.runTransaction(t => {
                    return t.get(mayorRef).then(snapshot => {
                        var new_budget = snapshot.data().b - 100;
                        return t.update(mayorRef, {b: new_budget});
                    })
            });
            return Promise.all([p1, p2]);
    });
    

    【讨论】:

    • 谢谢。有用。现在,如果一个操作失败了,我如何知道哪个操作失败了。如果他们两个都失败了怎么办?另外,我怎样才能为他们每个人实现一个单独的重试机制?
    • 我不认为Promise.all() 公开了足够的信息来确定什么承诺失败了。看看stackoverflow.com/questions/30362733/…
    猜你喜欢
    • 1970-01-01
    • 2013-04-14
    • 1970-01-01
    • 2020-06-28
    • 2017-09-24
    • 1970-01-01
    • 2012-01-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多