2017-07-25 113 views
1

我有異步調用和循環的問題。我現在面臨的是for循環在執行另一輪之前從不等待所有承諾完成。我的代碼框架這樣:JavaScript for循環不等待所有承諾執行

// removed code 

有沒有辦法做到這一點使得for循環將等待做了所有我的諾言執行另一輪之前執行?

+0

我看到裏面'snapshot.forEach'一個'resolve' ......這意味着你認爲你可以解決無極不止一次 –

+0

您可以設置一個標誌,檢查是否所有承諾已完成,並在每次承諾完成時檢查此標誌。 – huydq5000

+0

@JaromandaX對不起,你是什麼意思?這是錯的嗎? – guest176969

回答

1

你也可以做到這一點在調用它自身的功能:

function ramdomMerch (index, maxIndex) { 
    count = index; 
    count++; 
    if (count > maxIndex) { 
    exit(); //This will end the loop as soon as it hits the maxIndex 
    } 


    // random select merchant 
    let randomMerchantName = new Promise((resolve, reject) => { 
     merchantName = branchlist[branchIndex].merchantName; 
     resolve(merchantName); 
    }); 


      let promiseMerchantKey = new Promise((resolve, reject) => { 
       randomMerchantName.then((merchantName) => { 
       firebase.database().ref('merchants').orderByChild('merchantName').equalTo(merchantName).once('value', function(snapshot) { 
        var merchantData = snapshot.val(); 
        if (merchantData){ 
         console.log('merchant exists'); 
         snapshot.forEach(function(childSnapshot) { 
         var item = childSnapshot.val(); 
         item.key = childSnapshot.key; 
         resolve(item.key); 
         }); 
        }else{ 
         var merchantKey = firebase.database().ref('merchants').push({ 
         merchantName : merchantName 
         }).getKey(); 

         resolve(merchantKey); 
        } 
        ramdomMerch(count, maxIndex); // Here we simply call after finish the next "loop" 
       }); 
       }); 
      }); 
} 

randomMerch(1, 10); //We start it like an loop with the start and endIndex 

一種更好的方式與承諾的工作是then運營商。 這將是一個語法像:

let promiseMerchantKey = new Promise((... 
promiseMerchantKey.then(function(value) { 
    // Sucess, call next promise or next loop if it was the last 
    }, function(reason) { 
    // error 
}); 
+0

很抱歉,上面的代碼是隨機選擇10次商家的權利?有什麼方法可以強制for循環在執行另一輪之前完成執行任何內容?因爲我的情況是,我想循環10次。每一次,我隨機生成類別,商家,分支和東西。在該循環中,我需要獲取隨機選擇的項目並插入到Firebase中。在我完成插入所有其他部分後,我再次運行。 – guest176969

+0

我只是將你的代碼複製到函數中,它實際上除了調用你的代碼10次之外沒有其他任何事情,並且等到1次運行完成之後才調用下一次代碼。您只需添加其餘的代碼並放置ramdomMerch(count,maxIndex);在你最後的承諾中。我認爲你想在你的插入諾言 – Doomenik

+0

對不起,但功能是像一個for循環?所以我只是把所有的承諾放在裏面,然後在最後一行我再次調用函數?它是否像Java一樣從上到下執行? – guest176969

0

我這裏寫了一個原型,希望幫助:

var donePromise = 0; 
let n = 10; 
for(let count = 0; count < n; count++){ 
    DoAPromisse(function() { 
     donePromise++; 

     if (donePromise == n) { 
      //all promisesses done 
     } 
    }); 
} 
+0

非常感謝! – guest176969

1

你想要的是連鎖的承諾。你可以做到這一點,像這樣:

//Just so we have a promise to start with for the chain. 
let promiseMerchantKey = Promose.resolve(); 
for(let count = 0; count < 10; count++){ 

// random select category from list 

// random select merchant 
let randomMerchantName = promiseMerchantKey.then(()=>{ 
    return new Promise((resolve, reject) => { 
     merchantName = branchlist[branchIndex].merchantName; 
     resolve(merchantName); 
    }) 
}); 

// create merchant 
// check if merchant exists before add 
promiseMerchantKey = randomMerchantName.then((marchantName)=>{ 
    return new Promise((resolve, reject) => { 
     firebase.database().ref('merchants').orderByChild('merchantName').equalTo(merchantName).once('value', function(snapshot) { 
        var merchantData = snapshot.val(); 
        if (merchantData){ 
         console.log('merchant exists'); 
         snapshot.forEach(function(childSnapshot) { 
         var item = childSnapshot.val(); 
         item.key = childSnapshot.key; 
         resolve(item.key); 
         }); 
        }else{ 
         var merchantKey = firebase.database().ref('merchants').push({ 
         merchantName : merchantName 
         }).getKey(); 

         resolve(merchantKey); 
        } 
       }); 
       }); 
}); 


// all other promises to insert record into different child 

} 
+0

讓我們說我的promiseMerchantKey需要從3個不同的隨機承諾,例如,randomMerchantName,randomBranchAddress和randomBranchName,有反正這樣做嗎? – guest176969

+0

可以說有辦法這樣做是的。您可以創建3個承諾,將它們存儲在數組中並返回一個Promise.all(),以確保3個承諾在繼續之前完成。但是這超出了你的第一個問題的範圍。 – Salketer

+0

非常感謝! – guest176969