我有異步調用和循環的問題。我現在面臨的是for循環在執行另一輪之前從不等待所有承諾完成。我的代碼框架這樣:JavaScript for循環不等待所有承諾執行
// removed code
有沒有辦法做到這一點使得for循環將等待做了所有我的諾言執行另一輪之前執行?
我有異步調用和循環的問題。我現在面臨的是for循環在執行另一輪之前從不等待所有承諾完成。我的代碼框架這樣:JavaScript for循環不等待所有承諾執行
// removed code
有沒有辦法做到這一點使得for循環將等待做了所有我的諾言執行另一輪之前執行?
你也可以做到這一點在調用它自身的功能:
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
});
很抱歉,上面的代碼是隨機選擇10次商家的權利?有什麼方法可以強制for循環在執行另一輪之前完成執行任何內容?因爲我的情況是,我想循環10次。每一次,我隨機生成類別,商家,分支和東西。在該循環中,我需要獲取隨機選擇的項目並插入到Firebase中。在我完成插入所有其他部分後,我再次運行。 – guest176969
我只是將你的代碼複製到函數中,它實際上除了調用你的代碼10次之外沒有其他任何事情,並且等到1次運行完成之後才調用下一次代碼。您只需添加其餘的代碼並放置ramdomMerch(count,maxIndex);在你最後的承諾中。我認爲你想在你的插入諾言 – Doomenik
對不起,但功能是像一個for循環?所以我只是把所有的承諾放在裏面,然後在最後一行我再次調用函數?它是否像Java一樣從上到下執行? – guest176969
我這裏寫了一個原型,希望幫助:
var donePromise = 0;
let n = 10;
for(let count = 0; count < n; count++){
DoAPromisse(function() {
donePromise++;
if (donePromise == n) {
//all promisesses done
}
});
}
非常感謝! – guest176969
你想要的是連鎖的承諾。你可以做到這一點,像這樣:
//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
}
讓我們說我的promiseMerchantKey需要從3個不同的隨機承諾,例如,randomMerchantName,randomBranchAddress和randomBranchName,有反正這樣做嗎? – guest176969
可以說有辦法這樣做是的。您可以創建3個承諾,將它們存儲在數組中並返回一個Promise.all(),以確保3個承諾在繼續之前完成。但是這超出了你的第一個問題的範圍。 – Salketer
非常感謝! – guest176969
我看到裏面'snapshot.forEach'一個'resolve' ......這意味着你認爲你可以解決無極不止一次 –
您可以設置一個標誌,檢查是否所有承諾已完成,並在每次承諾完成時檢查此標誌。 – huydq5000
@JaromandaX對不起,你是什麼意思?這是錯的嗎? – guest176969