トップレベルでasync/awaitを使用するにはどうすればいいですか? 質問する

トップレベルでasync/awaitを使用するにはどうすればいいですか? 質問する

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関数がそうします。

最上位レベルでは、次のいずれかを実行する必要があります。

  1. トップレベルawait提案翻訳; ES2022,広く支持されているawaitモジュール内でのトップレベルの使用を可能にする、最新の環境で使用される です。

    または

  2. 決して拒否されないトップレベルasync関数を使用します (「未処理の拒否」エラーが発生しない限り)。

    または

  3. thenおよび を使用しますcatch

awaitモジュール内のトップレベル 1

awaitモジュールのトップレベルで使用できます。モジュールは、Promiseawaitが解決されるまで読み込みが完了しません (つまり、モジュールの読み込みを待機しているモジュールは、Promise が解決されるまで読み込みが完了しません)。Promise が拒否された場合、モジュールは読み込みに失敗します。通常、トップレベルは、awaitPromise が解決されるまでモジュールが作業を実行できず、Promise が満たされない限りまったく作業を実行できない状況で使用されます。したがって、問題ありません。

const text = await main();
console.log(text);

プロミスが拒否されてもモジュールが動作し続ける場合は、トップレベルを/awaitでラップできます。trycatch

// 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ではなく) 関数を介して呼び出した結果に対してこれを行うこともできます。trycatch

(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コールバックもエラーをスローしないことを確認してください。

おすすめ記事