2017-12-29 23 views
1

Ich habe eine Schleife, die eine Reihe von Benutzern durchläuft, diese Schleife ist asynchron, was ich tun möchte, ist für jeden Benutzer ein neues Dokument erstellen und speichern und warten auf diese zu speichern und dann weiter zum nächsten Benutzer. Ich bin in der Lage, mit dem nächsten Benutzer umzugehen, also ist mein Problem beim Speichern der neuen Dokumentdaten. Ich benutze Mungo-Safe-Methode.Warten Sie auf Speichern, bevor Sie mit der Funktion fortfahren

Die Hauptfunktion läuft die Schleife, hier ist ein Beispiel. Anmerkung: 'Async' ist das Modul async V2.6.0

async.forEach(users, (user, callback)=>{ 
    console.log(`Checking ${user.first_name}`); 
    createNewDocument(user, (err)=>{ 
      if(!err) { 
       console.log("New document created."); 
       callback(); 
      } 
    }, (err)=>{ 
     if(!err){ 
      console.log("All users were updated"); 
     } 
    }); 
} 

Die nicht-Async Methode

users.forEach((user)=>{ 
    console.log(`Checking ${user.first_name}`); 
    createNewDocument(user, (err)=>{ 
     if(!err) { 
       console.log("New document created."); 
      } 
    }); 
}); 

Die Funktion createNewDocument

function createNewDocument(user, callback) 
{ 
     console.log("Creating a new doc..."); 
     let doc = new Doc(); 
     doc.save((err)=>{ 
     if(!err){ 
      console.log(`New doc created for user ${user.first_name}`); 
      callback; 
     } 
     }); 
     console.log("Creating a new doc finished executing..."); 
} 

Alles ausgeführt wird und die letzte Sache, die ich in meinem Protokoll bekomme, ist ein Bündel von "Neues Dokument erstellt für Benutzer ...." für alle Benutzer. Ich habe eine ganze Menge probiert, ich habe versucht, die doc.save in ein Versprechen zu setzen, aber das hat nicht so gut funktioniert, nicht sicher, was ich jetzt tun soll.

BEARBEITEN: Es ist wichtig für mich, das neue Dokument zu erstellen, bevor ich zum nächsten Benutzer gehe, ich möchte sie nicht zum Aufruf-Array hinzufügen und dann ausführen, ich muss das vorherige Dokument überprüfen existieren tatsächlich und nehmen einige Daten davon beim nächsten Mal, wenn die Schleife eintritt

+0

„was ich tun möchte, ist für jeden Benutzer ein neues Dokument erstellen und speichern und warten Sie, diese zu speichern und dann zu den nächsten Benutzer weitergehen“ . Warum verwenden Sie eine asynchrone Schleife? Der gesamte Punkt von async ist NICHT zu warten. – gforce301

+0

Ich habe zuvor keine asynchrone Schleife verwendet und es führte zum selben Problem, bis jemand anwies, async zu verwenden, und das war mein exakter Punkt, dass async nicht warten soll, und sie sagten, der Callback würde das kontrollieren. –

+0

"Callbacks" haben wirklich nichts mit Async-Verhalten zu tun. Es gibt viele Synchronisierungsfunktionen, die Rückrufe verwenden. Das native 'Array.forEach' verwendet eins. – gforce301

Antwort

0

Es gab Versprechungen für verschachtelte Async und ordnungsgemäße Fehlerbehandlung seit Jahren. Kürzlich gibt es die async und await Syntax, um Versprechen wie C# -Code zu machen, aber die wichtige Sache ist zu lernen, wie Versprechen funktionieren, weil diese Syntax Versprechungen verwendet.

Versprechen verwenden Sie können wie folgt vorgehen:

const createNewDocument = user => 
    new Promise(
    (resolve,reject) => { 
     console.log("Creating a new doc..."); 
     let doc = new Doc(); 
     doc.save(
     err=>{ 
      console.log("Creating a new doc finished executing..."); 
      err 
      ? reject(err) 
      : resolve(`New doc created for user ${user.first_name}`) 
     } 
    );  
    } 
); 

const saveDocuments = (users,processedSoFar=[]) => { 
    if(users.length===0){ 
    return processedSoFar; 
    } 
    console.log(`Checking ${users[0].first_name}`); 
    return createNewDocument(users[0]) 
    .then(
    result=>{ 
     console.log("New document created."); 
     processedSoFar.push(users[0]); 
     return saveDocuments(users.slice(1),processedSoFar);  
    } 
) 
    .catch(
    err=>Promise.reject([err,processedSoFar]) 
); 
} 

saveDocuments(users) 
.then(
    result=>{ 
    console.log("Processed the following users:",users); 
    } 
) 
.catch(
    ([err,processed])=>{ 
    console.log(
     "Something went wrong:",err, 
     "Processed so far:",processed 
    ) 
    } 
) 
Verwandte Themen