いくつかのレベルで、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
場合 どちらの場合も、値が返されるか、例外がスローされます。