如何确保云功能中的所有操作都已成功完成?

问题描述 投票:0回答:1

我正在使用Firebase云功能,这些功能由在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个回答
2
投票

每当你有这样的多个操作时,解决方案是使用Promise.all()。这需要一系列承诺,然后返回一个承诺,当您传入的所有承诺都得到解决时,该承诺会解决。

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]);
});
© www.soinside.com 2019 - 2024. All rights reserved.