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.