sql >> Database teknologi >  >> NoSQL >> MongoDB

Mongoose sender data ud af withTransaction helper

Det ser ud til, at der er en vis forvirring her om, hvordan man bruger løfter korrekt på flere niveauer.

Callback og Promise bliver brugt forkert

Hvis funktionen formodes at acceptere et tilbagekald, skal du ikke returnere et løfte. Hvis funktionen skal returnere et løfte, skal du bruge tilbagekaldet givet af 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")
            }
        });
    })

Lad os se på dette mere detaljeret:

return new Promise( (resolve, reject) => { Dette skaber et nyt løfte, og løftet giver dig to tilbagekald til brug. resolve er et tilbagekald for at indikere succes. Du giver den den genstand, du gerne vil returnere. Bemærk, at jeg har fjernet async søgeord (mere om dette senere).

For eksempel:

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

(err, testData) => { Denne funktion bruges til at kortlægge node-stilen cb(err, result) til Løftets tilbagekald.

Try/catch bliver brugt forkert.

Try/catch kan kun bruges til synkrone udsagn. Lad os sammenligne et synkront opkald, en node-stil (dvs. cb(err, result) ) asynkront tilbagekald, et løfte og brug afventer:

  • Synkron:
try {
    let a = doSomethingSync();
} catch(err) {
    handle(err);
}
  • Asynkron:
doSomethingAsync( (err, result) => {
    if (err) {
        handle(err);
    } else {
        let a = result;
    }
});
  • Løver:
doSomethingPromisified()
    .then( (result) => { 
        let a = result; 
    })
    .catch( (err) => {
        handle(err);
    });
  • Vent. Await kan bruges med enhver funktion, der returnerer et løfte, og lader dig håndtere koden, som om den var synkron:
try {
    let a = await doSomethingPromisified();
} catch(err) {
    handle(err);
}

Yderligere oplysninger

Promise.resolve()

Promise.resolve() opretter et nyt løfte og løser det løfte med en udefineret værdi. Dette er en forkortelse for:

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

Tilbagekaldssvaret til dette ville være:

cb(err, undefined);

async

async går med await . Hvis du bruger await i en funktion skal denne funktion erklæres for at være async .

Ligesom await udpakker et løfte (resolve ind i en værdi, og reject ind i en undtagelse), async omslag kode til et løfte. En return value sætning bliver oversat til Promise.resolve(value) , og en smidt undtagelse throw e bliver oversat til Promise.reject(e) .

Overvej følgende kode

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

Ovenstående kode svarer til dette:

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

Hvis du kalder en af ​​ovenstående funktioner uden await , vil du få et løfte tilbage. Hvis du await enten af ​​dem, vil du blive returneret en værdi, eller en undtagelse vil blive kastet.




  1. Samtidsoptælling ved hjælp af Mongo-aggregationsramme

  2. Hvis jeg har et mongo-dokument-id som en streng, hvordan forespørger jeg efter det som et _id?

  3. Spring Boot Data og MongoDB - Filter Subdocument Array Query

  4. Masseopdatering af matchende underdokument i Mongodb