簡體   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