Het lijkt erop dat er hier enige verwarring bestaat over het correct gebruiken van Beloften, op verschillende niveaus.
Terugbellen en belofte worden onjuist gebruikt
Als de functie een callback moet accepteren, retourneer dan geen belofte. Als de functie een Belofte moet retourneren, gebruik dan de callback die door de Belofte wordt gegeven:
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")
}
});
})
Laten we dit in meer detail bekijken:
return new Promise( (resolve, reject) => {
Dit creëert een nieuwe belofte en de belofte geeft je twee callbacks om te gebruiken. resolve
is een callback om succes aan te geven. U geeft het object door dat u wilt retourneren. Merk op dat ik de async
. heb verwijderd zoekwoord (hierover later meer).
Bijvoorbeeld:
const a = new Promise( (resolve, reject) => resolve(5) );
a.then( (result) => result == 5 ); //true
(err, testData) => {
Deze functie wordt gebruikt om de Node-stijl cb(err, result)
naar de callbacks van de Promise.
Try/catch worden onjuist gebruikt.
Try/catch kan alleen worden gebruikt voor synchrone statements. Laten we een synchrone oproep vergelijken, een Node-stijl (d.w.z. cb(err, result)
) asynchroon terugbellen, een belofte en gebruik van wait:
- Synchroon:
try {
let a = doSomethingSync();
} catch(err) {
handle(err);
}
- Async:
doSomethingAsync( (err, result) => {
if (err) {
handle(err);
} else {
let a = result;
}
});
- Beloof:
doSomethingPromisified()
.then( (result) => {
let a = result;
})
.catch( (err) => {
handle(err);
});
- Wacht af. Await kan worden gebruikt met elke functie die een belofte retourneert, en laat je de code behandelen alsof deze synchroon is:
try {
let a = await doSomethingPromisified();
} catch(err) {
handle(err);
}
Aanvullende informatie
Promise.resolve()
Promise.resolve()
creëert een nieuwe belofte en lost die belofte op met een ongedefinieerde waarde. Dit is een afkorting voor:
new Promise( (resolve, reject) => resolve(undefined) );
Het callback-equivalent hiervan zou zijn:
cb(err, undefined);
async
async
hoort bij await
. Als u await
gebruikt in een functie moet die functie worden gedeclareerd als async
.
Net als await
pakt een belofte uit (resolve
in een waarde, en reject
in een uitzondering), async
wraps code in een belofte. Een return value
statement wordt vertaald in Promise.resolve(value)
, en een gegenereerde uitzondering throw e
wordt vertaald in Promise.reject(e)
.
Overweeg de volgende code
async () => {
return doSomethingSync();
}
De bovenstaande code komt hiermee overeen:
() => {
const p = new Promise(resolve, reject);
try {
const value = doSomethingSync();
p.resolve(value);
} catch(e) {
p.reject(e);
}
return p;
}
Als u een van de bovenstaande functies aanroept zonder await
, krijgt u een Belofte terug. Als je await
een van beide, je krijgt een waarde terug, of er wordt een uitzondering gegenereerd.