繁体   English   中英

有什么办法可以破坏匿名函数中的Javascript函数?

[英]Is there any way to break Javascript function within an anonymous function?

我只想检查我即将在Firebase上插入所有准备就绪的数据,如果是这样,我只想破坏add函数:

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”传递给主作用域。

如果添加一些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.之后立即触发。 这是因为on从Firebase开始异步加载数据。 并且由于这需要时间,因此浏览器在该块之后继续执行代码。 从Firebase的服务器下载数据后,它将调用回调,您可以执行所需的操作。 但是到那时,原始上下文已经完成。

JavaScript中没有办法等待异步函数完成。 尽管您可能会喜欢这种方法,但您对用户的失望是,在您对Firebase的呼叫中断时,他们的浏览器锁定了。

相反,您有两个选择:

  1. 将回调传递给函数
  2. 兑现承诺

我将使用下面的选项1,因为它是Firebase JavaScript SDK已经执行的操作。

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');
};

请注意,从服务器加载所有活动以检查特定的活动名称是否已经存在非常浪费。 如果您希望广告系列名称唯一,则最好按名称存储广告系列。

CampaignsRef.child(campaign.Name).set(campaign);

从Firebase文档中,如果您的回调函数“通过返回true取消枚举”,则snapshot.forEach返回true 因此,只需将return false更改为return true

在中断之前,在forEach循环中设置一个“全局”(对addCampaign函数)标志,然后在返回主函数并返回是否已设置时检查此标志。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM