sql >> Databasteknik >  >> NoSQL >> MongoDB

Mongoose skickar data från withTransaction helper

Det verkar som att det finns en viss förvirring här om hur man korrekt använder Promises, på flera nivåer.

Callback och Promise används felaktigt

Om funktionen är tänkt att acceptera en återuppringning, returnera inte ett löfte. Om funktionen är tänkt att returnera ett löfte, använd återuppringningen från löftet:

const transactionSession = await mongoose.startSession()
await transactionSession.withTransaction( (tSession) => {
    return new Promise( (resolve, reject) => {
        //using Node-style callback
        doSomethingAsync( (err, testData) => {
            if(err) {
                reject(err);
            } else {
                resolve(testData); //this is the equivalent of cb(null, "Any test data")
            }
        });
    })

Låt oss titta på detta mer i detalj:

return new Promise( (resolve, reject) => { Detta skapar ett nytt löfte, och löftet ger dig två återuppringningar att använda. resolve är en återuppringning för att indikera framgång. Du skickar det objektet du vill lämna tillbaka. Observera att jag har tagit bort async nyckelord (mer om detta senare).

Till exempel:

const a = new Promise( (resolve, reject) => resolve(5) );
a.then( (result) => result == 5 ); //true

(err, testData) => { Denna funktion används för att mappa nodstilen cb(err, result) till löftets återuppringningar.

Try/catch används felaktigt.

Try/catch kan endast användas för synkrona uttalanden. Låt oss jämföra ett synkront anrop, en nodstil (dvs. cb(err, result) ) asynkron återuppringning, ett löfte och användning av väntar:

  • Synkron:
try {
    let a = doSomethingSync();
} catch(err) {
    handle(err);
}
  • Asynk:
doSomethingAsync( (err, result) => {
    if (err) {
        handle(err);
    } else {
        let a = result;
    }
});
  • Lova:
doSomethingPromisified()
    .then( (result) => { 
        let a = result; 
    })
    .catch( (err) => {
        handle(err);
    });
  • Vänta. Await kan användas med vilken funktion som helst som returnerar ett löfte och låter dig hantera koden som om den vore synkron:
try {
    let a = await doSomethingPromisified();
} catch(err) {
    handle(err);
}

Ytterligare information

Promise.resolve()

Promise.resolve() skapar ett nytt löfte och löser det löftet med ett odefinierat värde. Detta är en förkortning för:

new Promise( (resolve, reject) => resolve(undefined) );

Återuppringningsmotsvarigheten till detta skulle vara:

cb(err, undefined);

async

async går med await . Om du använder await i en funktion måste den funktionen förklaras vara async .

Precis som await packar upp ett löfte (resolve till ett värde och reject till ett undantag), async omslag kod till ett löfte. Ett return value uttalande översätts till Promise.resolve(value) , och ett slängt undantag throw e översätts till Promise.reject(e) .

Tänk på följande kod

async () => {
    return doSomethingSync();
}

Koden ovan motsvarar detta:

() => {
    const p = new Promise(resolve, reject);
    try {
        const value = doSomethingSync();
        p.resolve(value);
    } catch(e) {
        p.reject(e);
    }
    return p;
}

Om du anropar någon av ovanstående funktioner utan att await , du kommer att få tillbaka ett löfte. Om du await någon av dem kommer du att få ett värde tillbaka, eller så kommer ett undantag att kastas.




  1. Draft.js - Kan inte hämta data från databasen. Cross-origin fel

  2. new Date() i sammanlagt $project

  3. Swagger (Swashbuckle för C#) visar Mongo ObjectId som flera fält istället för en enda sträng

  4. Hur man ansluter till MongoDB EC2-instans