有没有办法在匿名函数中打破Javascript函数?

时间:2015-06-25 15:38:46

标签: javascript firebase

我只是想检查我即将插入的数据是否已经存在于我的Firebase中,如果是这样,我只想打破添加功能:

FBDB.addCampain=function (campain){

        CampiansRef.once('value',function(snapshot){
        snapshot.forEach(function(childSnapshot){
           if(campain.Name==childSnapshot.val().Name){
               console.log("campain allredy exists on the DB");
              return false; //I want to break the addCampain function from here!
           }
         });
        });

   var newCampainRef =  CampiansRef.push();
   campain.id = newCampainRef.key();
   newCampainRef.set(campain,function(error){
       if(error){
           console.log("an error occured the campain did not add to the DB, error:" ,+error);
           return false;
       }
       else{
           console.log("campain succssesfuly added to the DB");
           return true;
       }
   });

};

目前发生的情况是,即使广告系列存在于数据库中,它仍然会继续使用实际的添加代码。必须有一种方法可以在其中的匿名函数中“中断”addCampain函数,或者甚至将“return false”传递给主范围。

3 个答案:

答案 0 :(得分:3)

如果您添加一些~/.bundle语句,您将能够看到代码的流程:

console.log

输出如下:

console.log('1. starting call to Firebase');
CampaignsRef.once('value',function(snapshot){
    console.log('3. for value from Firebase');
    snapshot.forEach(function(childSnapshot){
        console.log('4. inside childSnapshot');
        if (campaign.Name==childSnapshot.val().Name){
            console.log("campaign already exists on the DB");
            return false;
        }
        console.log('5. done with snapshot.forEach');
    });
});
console.log('2. we started the call to Firebase');

这可能不完全符合您的预期。 1. starting call to Firebase 2. we started the call to Firebase 3. for value from Firebase 4. inside childSnapshot 4. inside childSnapshot 4. inside childSnapshot 5. done with snapshot.forEach 位于代码块的末尾,但它会在2.之后立即触发。这是因为1.启动了Firebase数据的异步加载。由于这需要时间,因此浏览器会在块之后继续执行代码。从Firebase的服务器下载数据后,它将调用回调,您可以执行所需的操作。但到那时,原始背景已经结束。

JavaScript中无法等待异步函数完成。虽然如果存在这种方式,您可能会感到欣慰,但是当您的Firebase呼叫结束时,您的用户会因为浏览器锁定而感到沮丧。

相反,您有两种选择:

  1. 将回调传递给函数
  2. 返回承诺
  3. 我将使用下面的选项1,因为它是Firebase JavaScript SDK已经完成的工作。

    on

    你可以这样调用:

    FBDB.addCampaign=function (campaign, callback){
        CampaignsRef.once('value',function(snapshot){
            var isExisting = snapshot.forEach(function(childSnapshot){
                if(campaign.Name==childSnapshot.val().Name){
                    return true; // this cancels the enumeration and returns true to indicate the campaign already exists
                }
            });
            callback(isExisting);
        });
    };
    

    请注意,从服务器加载所有广告系列以检查特定广告系列名称是否已存在非常浪费。如果您希望广告系列名称具有唯一性,您也可以按名称存储广告系列。

    FB.addCampaign(campaign, function(isExisting) {
        console.log(isExisting ? 'The campaign already existed' : 'The campaign was added');
    };
    

答案 1 :(得分:0)

从Firebase文档中,如果您的回调函数"通过返回snapshot.forEach"取消枚举,则true会返回true。所以只需将return false更改为return true

答案 2 :(得分:0)

在打开它之前在addCampaign循环中设置一个“全局”(到你的forEach函数)标志,然后当你回到主函数时检查这个标志并返回它已经确定了。