TypeScript - Bulut fonksiyonu tüm kod çalışmadan önce sona eriyor


Bir bulut fonksiyonu oluşturmaya çalışıyorum, ancak Firebase'in loglarında tüm görevleri yapmadan önce 'tamamlandı' olarak görünüyor.

Bu benim kodum.

  export const count = functions.pubsub
  .schedule('0 8 * * *')
  .timeZone('Europe/Brussels')
  .onRun(async context => {

     const snapshot =  await admin.database().ref('/counter').once('value');

     snapshot.forEach( (child) =>
{
    var info = child.val();
    var dayViews = info['count'];
    var ID = child.key;

        var ref1 = admin.database().ref('/counter/'+ID);
        ref1
        .update({
          "count": 0,
          "totalViews": dayViews,
        })
        .then(function() {
          console.log("Write completed")
        }).catch(function(error) {
          console.error("Write failed: "+error)
        });

    });
    return 0;

  });

Bence sorun, fonksiyonun for each döngüsünü bitirmeden önce 0 döndürmesi.

Bunun bir çözümü var mı?

Teşekkürler!

Cevap #1

Çözüm, return çağırmadan önce tüm asenkron update() işlemlerinin tamamlanmasını beklemektir: bir forEach() döngüsü kullandığınız için, döngüde çağrılan tüm asenkron işlemlerin tamamlanmasını beklemek için Promise.all() kullanmanız gerekir, böylece döndürdüğü Promise tamamlanmadan return çağrılmaz.

Belgede açıklandığı gibi (yukarıdaki bağlantı), Promise.all() "genellikle birden fazla eşzamansız görevi aynı anda çalıştırmaya başladıktan ve sonuçları için sözler (promises) oluşturduktan sonra kullanılır, böylece tüm görevlerin bitmesini bekleyebilirsiniz".

Aşağıdakiler işe yarayacaktır:

export const count = functions.pubsub
    .schedule('0 8 * * *')
    .timeZone('Europe/Brussels')
    .onRun(async context => {

        const snapshot = await admin.database().ref('/counter').once('value');

        const promises = [];

        snapshot.forEach((child) => {
            var info = child.val();
            var dayViews = info['count'];
            var ID = child.key;

            var ref1 = admin.database().ref('/counter/' + ID);

            promises.push(ref1
                .update({
                    "count": 0,
                    "totalViews": dayViews,
                }));
        });

        return Promise.all(promises)

    });

Bir Bulut Fonksiyonunda eşzamanlı olmayan işlemleri doğru şekilde yönetmenin neden önemli olduğu hakkında, Firebase video serisinden "JavaScript Promises" ile ilgili 3 videoyu izlemenizi öneririm: https://firebase.google.com/docs/functions/video-series/