いくつかのレベルで、Promisesを正しく使用する方法に関してここでいくつかの混乱があるようです。
コールバックとプロミスが正しく使用されていません
関数がコールバックを受け入れることになっている場合は、Promiseを返さないでください。関数がPromiseを返すことになっている場合は、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")
}
});
})
これをもっと詳しく見てみましょう:
return new Promise( (resolve, reject) => { これにより、新しいPromiseが作成され、Promiseは使用する2つのコールバックを提供します。 resolve 成功を示すコールバックです。返したいオブジェクトを渡します。 asyncを削除したことに注意してください キーワード(これについては後で詳しく説明します)。
例:
const a = new Promise( (resolve, reject) => resolve(5) );
a.then( (result) => result == 5 ); //true
(err, testData) => { この関数は、ノードスタイルのcb(err, result)をマップするために使用されます。 Promiseのコールバックに。
try/catchが正しく使用されていません。
try / catchは、同期ステートメントにのみ使用できます。同期呼び出し、ノードスタイル(つまり、cb(err, result)を比較してみましょう )非同期コールバック、Promise、およびawaitの使用:
- 同期:
try {
let a = doSomethingSync();
} catch(err) {
handle(err);
}
- 非同期:
doSomethingAsync( (err, result) => {
if (err) {
handle(err);
} else {
let a = result;
}
});
- 約束:
doSomethingPromisified()
.then( (result) => {
let a = result;
})
.catch( (err) => {
handle(err);
});
- お待ちください。 Awaitは、Promiseを返す任意の関数で使用でき、同期しているかのようにコードを処理できます。
try {
let a = await doSomethingPromisified();
} catch(err) {
handle(err);
}
追加情報
Promise.resolve()
Promise.resolve() 新しいPromiseを作成し、そのPromiseを未定義の値で解決します。これは略記です:
new Promise( (resolve, reject) => resolve(undefined) );
これに相当するコールバックは次のようになります:
cb(err, undefined);
async
async awaitと一緒に行く 。 awaitを使用している場合 関数では、その関数をasyncとして宣言する必要があります 。
awaitと同じように Promiseのラップを解除します(resolve 値に変換し、reject 例外に)、async ラップ Promiseにコード化します。 return value ステートメントはPromise.resolve(value)に変換されます 、およびスローされた例外throw e Promise.reject(e)に変換されます 。
次のコードを検討してください
async () => {
return doSomethingSync();
}
上記のコードはこれと同等です:
() => {
const p = new Promise(resolve, reject);
try {
const value = doSomethingSync();
p.resolve(value);
} catch(e) {
p.reject(e);
}
return p;
}
awaitなしで上記の関数のいずれかを呼び出す場合 、あなたは約束を取り戻すでしょう。 await場合 どちらの場合も、値が返されるか、例外がスローされます。