Es sieht so aus, als gäbe es hier einige Verwirrung darüber, wie Promises auf mehreren Ebenen korrekt verwendet werden.
Callback und Promise werden falsch verwendet
Wenn die Funktion einen Rückruf akzeptieren soll, geben Sie kein Promise zurück. Wenn die Funktion ein Promise zurückgeben soll, verwenden Sie den vom Promise gegebenen Callback:
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")
}
});
})
Sehen wir uns das genauer an:
return new Promise( (resolve, reject) => {
Dadurch wird ein neues Promise erstellt, und das Promise gibt Ihnen zwei Rückrufe zur Verwendung. resolve
ist ein Rückruf, um den Erfolg anzuzeigen. Sie übergeben ihm das Objekt, das Sie zurückgeben möchten. Beachten Sie, dass ich async
entfernt habe Schlüsselwort (dazu später mehr).
Zum Beispiel:
const a = new Promise( (resolve, reject) => resolve(5) );
a.then( (result) => result == 5 ); //true
(err, testData) => {
Diese Funktion wird verwendet, um den Node-Stil cb(err, result)
abzubilden zu den Rückrufen des Versprechens.
Try/Catch werden falsch verwendet.
Try/Catch kann nur für synchrone Anweisungen verwendet werden. Vergleichen wir einen synchronen Aufruf im Node-Stil (z. B. cb(err, result)
) asynchroner Rückruf, ein Promise und die Verwendung von await:
- Synchron:
try {
let a = doSomethingSync();
} catch(err) {
handle(err);
}
- Asynchron:
doSomethingAsync( (err, result) => {
if (err) {
handle(err);
} else {
let a = result;
}
});
- Versprechen:
doSomethingPromisified()
.then( (result) => {
let a = result;
})
.catch( (err) => {
handle(err);
});
- Warte. Await kann mit jeder Funktion verwendet werden, die ein Promise zurückgibt, und Sie können den Code so behandeln, als wäre er synchron:
try {
let a = await doSomethingPromisified();
} catch(err) {
handle(err);
}
Zusätzliche Informationen
Promise.resolve()
Promise.resolve()
erstellt ein neues Promise und löst dieses Promise mit einem undefinierten Wert auf. Dies ist eine Abkürzung für:
new Promise( (resolve, reject) => resolve(undefined) );
Das Callback-Äquivalent dazu wäre:
cb(err, undefined);
async
async
geht mit await
. Wenn Sie await
verwenden in einer Funktion muss diese Funktion als async
deklariert werden .
Genau wie await
entpackt ein Versprechen (resolve
in einen Wert und reject
in eine Ausnahme), async
Wraps Code in ein Versprechen. Ein return value
-Anweisung wird in Promise.resolve(value)
übersetzt , und eine ausgelöste Ausnahme throw e
wird in Promise.reject(e)
übersetzt .
Betrachten Sie den folgenden Code
async () => {
return doSomethingSync();
}
Der obige Code entspricht dem:
() => {
const p = new Promise(resolve, reject);
try {
const value = doSomethingSync();
p.resolve(value);
} catch(e) {
p.reject(e);
}
return p;
}
Wenn Sie eine der obigen Funktionen ohne await
aufrufen , erhalten Sie ein Versprechen zurück. Wenn Sie await
In beiden Fällen erhalten Sie einen Wert zurück oder es wird eine Ausnahme ausgelöst.