当forEach函数结束时需要执行函数

时间:2017-01-26 06:35:09

标签: node.js asynchronous firebase foreach firebase-realtime-database

我在节点js / firebase中有这段代码:

ref.child("recipts").once("value", function(usersSnap) {
    usersSnap.forEach(function(reciptsSnap) {  
      reciptsSnap.forEach(function(reciptSnap) {

        reciptSnap.ref.child("last_recipt").once("value", function(b) {
          b.forEach(function(c) {  //Here I fill some "product" object
              });
        });

        reciptSnap.forEach(function(b) { //Here I fill some "product" object
        });

      });
    });
  });

我需要在“reciptSnap”forEachs完成时执行一个函数。我怎样才能实现这一点,我尝试使用变量i ++和i--但只适用于一个forEach迭代。 我调用的函数用于操作我使用来自forEachs循环的填充数据创建的产品对象。

2 个答案:

答案 0 :(得分:2)

如果我理解正确,你想在reciptsSnap.forEach完成时调用一个函数,并且其中的所有异步任务也完成。

为实现此目的,您可以使用index参数和传递给forEach的callback函数的原始数组。 (See Documentation

代码将是这样的:

注意以下代码不会更改当前使用的forEach循环结构。但是,使用Promiseasync重写代码将是更好,更清洁的方式)。

var loop1Done = false;
var loop2Done = false;

ref.child("recipts").once("value", function (usersSnap) {
    usersSnap.forEach(function (reciptsSnap) {
        reciptsSnap.forEach(function (reciptSnap, index, colA) {

            const idx = index;
            const col = colA;

            reciptSnap.ref.child("last_recipt").once("value", function (b) {

                const i = idx;
                const c = col;

                b.forEach(function (c, j, colB) {  //Here I fill some "product" object

                    // Do what you want here

                    // Check if all done for this loop
                    if ((j >= colB.length) && (i >= c.length)) {

                        loop1Done = true;

                        // Check if all loops done
                        if (loop1Done && loop2Done) {
                            // Call final callback function
                            // e.g. myFinalCallback();
                        }
                    }
                });
            });

            reciptSnap.forEach(function (b, k, colC) { //Here I fill some "product" object

                const i = idx;
                const c = col;

                // Do what you want here

                // Check if all done for this loop
                if ((k >= colC.length) && (i >= c.length)) {

                    loop2Done = true;

                    // Check if all loops done
                    if (loop1Done && loop2Done) {
                        // Call final callback function
                        // e.g. myFinalCallback();
                    }
                }
            });

        });
    });
});

答案 1 :(得分:1)

尝试:

   reciptSnap.child("last_recipt").forEach(function(b) {
      b.forEach(function(c) {
               //Here I fill some "product" object
      });
   });

这应该有效,因为你所做的所有数据都已经被提取了,并且#34;值"在收据节点上。

如果这样做,你的代码不再是异步的,就在最后一个forEach之后,你可以执行你想要的功能。

    reciptSnap.forEach(function(b) {
        //Here I fill some "product" object
    });
    //Execute your function here
  });