Il semble qu'il y ait une certaine confusion ici quant à la façon d'utiliser correctement Promesses, à plusieurs niveaux.
Le rappel et la promesse ne sont pas utilisés correctement
Si la fonction est censée accepter un rappel, ne renvoyez pas de Promise. Si la fonction est censée renvoyer une Promise, utilisez le callback donné par la Promise :
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")
}
});
})
Regardons cela plus en détail :
return new Promise( (resolve, reject) => {
Cela crée une nouvelle promesse, et la promesse vous donne deux rappels à utiliser. resolve
est un rappel pour indiquer le succès. Vous lui passez l'objet que vous souhaitez rendre. Notez que j'ai supprimé le async
mot-clé (plus à ce sujet plus tard).
Par exemple :
const a = new Promise( (resolve, reject) => resolve(5) );
a.then( (result) => result == 5 ); //true
(err, testData) => {
Cette fonction est utilisée pour mapper le cb(err, result)
de style Node aux rappels de la Promesse.
Try/catch sont utilisés de manière incorrecte.
Try/catch ne peut être utilisé que pour les instructions synchrones. Comparons un appel synchrone, un style Node (c'est-à-dire cb(err, result)
) rappel asynchrone, une promesse et en utilisant await :
- Synchrone :
try {
let a = doSomethingSync();
} catch(err) {
handle(err);
}
- Asynchrone :
doSomethingAsync( (err, result) => {
if (err) {
handle(err);
} else {
let a = result;
}
});
- Promesse :
doSomethingPromisified()
.then( (result) => {
let a = result;
})
.catch( (err) => {
handle(err);
});
- Attendez. Await peut être utilisé avec n'importe quelle fonction qui renvoie une promesse et vous permet de gérer le code comme s'il était synchrone :
try {
let a = await doSomethingPromisified();
} catch(err) {
handle(err);
}
Informations supplémentaires
Promise.resolve()
Promise.resolve()
crée une nouvelle promesse et résout cette promesse avec une valeur indéfinie. C'est un raccourci pour :
new Promise( (resolve, reject) => resolve(undefined) );
L'équivalent de rappel de ceci serait :
cb(err, undefined);
async
async
va avec await
. Si vous utilisez await
dans une fonction, cette fonction doit être déclarée async
.
Tout comme await
déballe une promesse (resolve
en une valeur, et reject
dans une exception), async
enveloppements code dans une promesse. Une return value
l'instruction est traduite en Promise.resolve(value)
, et une exception levée throw e
est traduit en Promise.reject(e)
.
Considérez le code suivant
async () => {
return doSomethingSync();
}
Le code ci-dessus est équivalent à ceci :
() => {
const p = new Promise(resolve, reject);
try {
const value = doSomethingSync();
p.resolve(value);
} catch(e) {
p.reject(e);
}
return p;
}
Si vous appelez l'une des fonctions ci-dessus sans await
, vous récupérerez une Promesse. Si vous await
l'un ou l'autre, une valeur vous sera renvoyée ou une exception sera levée.