だから、私は私の最初のレベルのキャッチがエラーを処理するものであることを望みます。とにかく、最初のキャッチまでエラーを伝播する方法はありますか?
参照コード、(まだ)機能していません:
Promise = require('./framework/libraries/bluebird.js');
function promise() {
var promise = new Promise(function(resolve, reject) {
throw('Oh no!');
});
promise.catch(function(error) {
throw(error);
});
}
try {
promise();
}
// I WANT THIS CATCH TO CATCH THE ERROR THROWN IN THE PROMISE
catch(error) {
console.log('Caught!', error);
}
新しい async/await構文 を使用すると、これを実現できます。執筆の時点では、これはすべてのブラウザでサポートされているわけではないことに注意してください。おそらく babel (または類似の何か)を使用してコードをトランスパイルする必要があります。
// Because of the "async" keyword here, calling getSomeValue()
// will return a promise.
async function getSomeValue() {
if (somethingIsNotOk) {
throw new Error('uh oh');
} else {
return 'Yay!';
}
}
async function() {
try {
// "await" will wait for the promise to resolve or reject
// if it rejects, an error will be thrown, which you can
// catch with a regular try/catch block
const someValue = await getSomeValue();
doSomethingWith(someValue);
} catch (error) {
console.error(error);
}
}
例外がスローされる前に関数が「戻った」ため、try-catchステートメントを使用して非同期にスローされた例外を処理することはできません。代わりに、_promise.then
_および_promise.catch
_メソッドを使用する必要があります。これらは、try-catchステートメントと同等の非同期メソッドを表します。
あなたがする必要があるのは、promiseを返し、別の_.catch
_をそれにチェーンすることです:
_function promise() {
var promise = new Promise(function(resolve, reject) {
throw('Oh no!');
});
return promise.catch(function(error) {
throw(error);
});
}
promise().catch(function(error) {
console.log('Caught!', error);
});
_
プロミスは連鎖可能であるため、プロミスがエラーを再スローすると、次の_.catch
_に委任されます。
ちなみに、throw
ステートメントを括弧で囲む必要はありません(_throw a
_はthrow(a)
と同じです)。
このコードをNode.jsで実行していて、何らかの理由でpromise
関数の編集が許可されていない場合は、ドメインを使用して編集できます。ドメインは対処するのが最も簡単なものではなく、特定の状況ではいくつかの厄介なEdgeケースがあることに注意してください。 本当に必要な場合を除き、代わりにpromiseを使用することを強くお勧めします。
いいえ!プロミスは本質的に非同期であるため、それは完全に不可能です。例外がスローされると、try-catch句の実行が終了します(タイムトラベルはまだ発明されていません)。
代わりに、すべての関数からpromiseを返し、それらにエラーハンドラーをフックします。
Promiseが確実に返されるようにする必要性がよくあり、ローカルエラーを処理してからオプションでそれを再スローする必要がほとんどあります。
function doSomeWork() {
return Promise.try(function() {
return request.get(url).then(function(response) {
// ... do some specific work
});
}).catch(function(err) {
console.log("Some specific work failed", err);
throw err; // IMPORTANT! throw unless you intend to suppress the error
});
}
この手法の利点((Promise.try/catch)は、簡単に見落とされる可能性のある解決/拒否の要件なしでPromiseチェーンを開始/保証し、デバッグの悪夢を生み出すことです。
edo の答えを拡張するには、待機したくない非同期関数のエラーをキャッチしたい場合。関数の最後にawaitステートメントを追加できます。
(async function() {
try {
const asyncResult = someAsyncAction();
// "await" will wait for the promise to resolve or reject
// if it rejects, an error will be thrown, which you can
// catch with a regular try/catch block
const someValue = await getSomeValue();
doSomethingWith(someValue);
await asyncResult;
} catch (error) {
console.error(error);
}
})();
someAsyncAction
が失敗した場合、catchステートメントがそれを処理します。