2017-07-25 5 views
1

Ich hatte ein Problem mit asynchronen Anruf und For-Schleife. Worauf ich jetzt schaue ist, dass die for-Schleife niemals auf alle Versprechen wartet, bevor sie eine weitere Runde ausführen. Mein Code Skelett als solche:Javascript für Schleife nicht warten auf alle Versprechen zu führen

// removed code 

Gibt es eine Möglichkeit, diese so zu tun, dass die for-Schleife für alle meine Versprechen warten getan Ausführung bevor eine neue Runde der Ausführung?

+0

ich ein 'resolve' innen' snapshot.forEach' sehen ... was bedeutet, denken Sie, ein Versprechen mehr als einmal –

+0

lösen können Sie ein Flag setzen kann, wenn alle überprüfen Versprechen gemacht und überprüfen Sie diese Flagge jedes Mal, wenn ein Versprechen gemacht wird. – huydq5000

+0

@JaromandaX Sorry, aber was meinst du? Ist es falsch? – guest176969

Antwort

1

Sie auch in einer Funktion zu tun, die es selbst nennt:

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 

Eine bessere Möglichkeit, mit dem Versprechen zu arbeiten, ist die then Betreiber. Es wäre eine Syntax wie:

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

Sorry, aber der obige Code ist nach dem Zufallsprinzip Händler für 10 Mal richtig gewählt? Gibt es eine Möglichkeit, die For-Schleife zu zwingen, die Ausführung von allem, was drin ist, zu beenden, bevor eine weitere Runde ausgeführt wird? Weil meine Situation ist, wollte ich 10 mal eine Schleife machen. Für jedes Mal erzeuge ich zufällig Kategorie, Händler, Filiale und so. Und innerhalb dieser Schleife muss ich den zufällig ausgewählten Gegenstand holen und in den Firebase einfügen. Nachdem ich fertig bin, füge alle anderen Teile ein, dann laufe ich das zweite Mal. – guest176969

+0

Ich habe nur Ihren Code innerhalb der Funktion kopiert, es tut nichts anderes als den Code 10 Mal aufzurufen und wartet, bis 1 Durchlauf beendet ist, bevor er den nächsten aufruft. Sie müssen einfach den Rest Ihres Codes hinzufügen und das ramdomMerch platzieren (count, maxIndex); in deinem letzten Versprechen. Ich denke du willst es in deinem Insert versprechen – Doomenik

+0

Sorry aber die Funktion ist sowas wie eine for-Schleife? Also setze ich einfach mein ganzes Versprechen ein, dann rufe ich die Funktion in der letzten Zeile noch einmal an? Führt es Top-Down wie Java aus? – guest176969

0

ich einen Prototyp hier schreiben, hoffen, dass Hilfe:

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

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

Vielen Dank !!! – guest176969

1

Was Sie wollen, ist zu Kette verspricht. Man könnte es wie so tun:

//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

Lässt saymy promiseMerchantKey von 3 verschiedenen zufälligen Versprechen, zum Beispiel randomMerchantName, randomBranchAddress und randomBranchName, gibt es sowieso, um es zu tun? – guest176969

+0

Sagen wir, es gibt einen Weg, ja zu tun. Sie können die 3 Versprechen erstellen, sie in Array speichern und eine Promise.all() zurückgeben, die sicherstellen wird, dass die 3 Versprechen gemacht werden, bevor Sie fortfahren. Aber das geht aus dem Rahmen Ihrer ersten Frage heraus. – Salketer

+0

Vielen Dank !!! – guest176969

Verwandte Themen