async
私は/を調べていてawait
、いくつかの記事を読んだ後、自分でテストしてみることにしました。しかし、なぜこれが機能しないのか理解できません。
async function main() {
var value = await Promise.resolve('Hey there');
console.log('inside: ' + value);
return value;
}
var text = main();
console.log('outside: ' + text);
コンソールには次のように出力されます (node v8.6.0) :
> 外側: [オブジェクト Promise]
> 中: こんにちは
関数内のログ メッセージが後で実行されるのはなぜですか? async
/await
が作成された理由は、非同期タスクを使用して同期実行を行うためだと思いました。
.then()
after を使用せずに関数内で返された値を使用する方法はありますかmain()
?
ベストアンサー1
なぜこれが機能しないのか、私には理解できません。
main
はPromise を返すため、すべてのasync
関数がそうします。
最上位レベルでは、次のいずれかを実行する必要があります。
トップレベル
await
(提案、翻訳; ES2022,広く支持されているawait
モジュール内でのトップレベルの使用を可能にする、最新の環境で使用される です。または
決して拒否されないトップレベル
async
関数を使用します (「未処理の拒否」エラーが発生しない限り)。または
then
および を使用しますcatch
。
await
モジュール内のトップレベル 1
await
モジュールのトップレベルで使用できます。モジュールは、Promiseawait
が解決されるまで読み込みが完了しません (つまり、モジュールの読み込みを待機しているモジュールは、Promise が解決されるまで読み込みが完了しません)。Promise が拒否された場合、モジュールは読み込みに失敗します。通常、トップレベルは、await
Promise が解決されるまでモジュールが作業を実行できず、Promise が満たされない限りまったく作業を実行できない状況で使用されます。したがって、問題ありません。
const text = await main();
console.log(text);
プロミスが拒否されてもモジュールが動作し続ける場合は、トップレベルを/await
でラップできます。try
catch
// In a module, once the top-level `await` proposal lands
try {
const text = await main();
console.log(text);
} catch (e) {
// Deal with the fact the chain failed
}
// `text` is not available here
トップレベルを使用するモジュールawait
が評価されると、モジュール ローダーにプロミスが返されます (関数と同様にasync
)。モジュール ローダーは、そのプロミスが解決されるまで待機してから、それに依存するモジュールの本体を評価します。
await
非モジュール スクリプトの最上位レベルでは使用できません。モジュール内でのみ使用できます。
#2 - 決して拒否しないトップレベルasync
関数
(async () => {
try {
const text = await main();
console.log(text);
} catch (e) {
// Deal with the fact the chain failed
}
// `text` is not available here
})();
// `text` is not available here, either, and code here is reached before the promise settles
// and before the code after `await` in the main function above runs
;に注意してくださいcatch
。他に何も行われないので、promise の拒否 / 非同期例外を処理する必要があります。それらを渡す呼び出し元がありません (上記の #1 とは異なり、"呼び出し元" はモジュール ローダーです)。必要に応じて、( /構文catch
ではなく) 関数を介して呼び出した結果に対してこれを行うこともできます。try
catch
(async () => {
const text = await main();
console.log(text);
})().catch(e => {
// Deal with the fact the chain failed
});
// `text` is not available here, and code here is reached before the promise settles
// and before the code after `await` in the main function above runs
...これはもう少し簡潔ですが、モデル ( async
/await
と明示的な Promise コールバック) が多少混在しており、通常はそうしないことをお勧めします。
または、もちろん、エラーを処理せず、「未処理の拒否」エラーのみを許可します。
#3 -then
そしてcatch
main()
.then(text => {
console.log(text);
})
.catch(err => {
// Deal with the fact the chain failed
});
// `text` is not available here, and code here is reached before the promise settles
// and the handlers above run
チェーンまたはハンドラーでエラーが発生した場合、ハンドラーcatch
が呼び出されますthen
。(catch
エラーを処理するためのものが登録されていないため、ハンドラーがエラーをスローしないようにしてください。)
または、両方の引数を次のように指定しますthen
。
main().then(
text => {
console.log(text);
},
err => {
// Deal with the fact the chain failed
}
);
// `text` is not available here, and code here is reached before the promise settles
// and the handlers above run
再度、拒否ハンドラを登録していることに注意してください。ただし、このフォームでは、エラーを処理するためのものが登録されていないため、どちらのthen
コールバックもエラーをスローしないことを確認してください。