1. ホーム
  2. javascript

[解決済み] 非同期関数の外側でawaitを使用する

2022-10-23 02:15:46

質問

私は2つの非同期関数を一緒に連結しようとしました。1つ目は条件付きの戻りパラメータを持っていて、2つ目が実行されるか、モジュールを終了させるかするからです。しかし、私は仕様で見つけることができない奇妙な動作を発見しました。

async function isInLobby() {
    //promise.all([chained methods here])
    let exit = false;
    if (someCondition) exit = true;
}

これは私のコードの断片です (完全なスコープを見ることができます。 ここで を参照してください)、それは単にプレイヤーがすでにロビーにいるかどうかをチェックするだけですが、それは関係ありません。

次に、この非同期関数があります。

async function countPlayer() {
    const keyLength = await scardAsync(game);
    return keyLength;
}

この関数は、もし exit === true .

を行おうとしたのですが

const inLobby = await isInLobby();

これは結果を待ち望むもので、私は inLobby を条件付きで実行するために countPlayer を条件付きで実行しましたが、詳細不明のtypeerrorを受け取りました。

なぜあなたは await アン async 関数のスコープの外側にある?シュガープロミスであることは分かっているので、連鎖的に then に連鎖しなければならないことは分かっていますが、なぜ countPlayer では別のプロミスを待つことが出来ますが、外では await isInLobby ?

どのように解決するのですか?

トップレベル await はサポートされていません。この理由については、標準化委員会でいくつかの議論があり、例えば このGithubの問題 .

また にあるthinkpieceもあります。 にも、トップレベルの await がなぜ悪いアイデアなのかについての考察があります。具体的には、以下のようなコードがある場合、彼はそれを提案しています。

// data.js
const data = await fetch( '/data.json' );
export default data;

現在 任意の をインポートするファイル data.js をインポートする ファイルはフェッチが完了するまで実行されないので、すべてのモジュールのロードがブロックされます。私たちはトップレベルの Javascript が同期的に予測可能に実行されることに慣れているので、これではアプリのモジュールの順序を推論するのが非常に難しくなります。これが許可されると、関数がいつ定義されるかを知ることが厄介になります。

私の見解 は、モジュールをロードするだけで副作用が発生するのはバッドプラクティスだということです。つまり、あなたのモジュールの消費者は、あなたのモジュールを必要とするだけで、副作用を受けることになります。これは、モジュールが使用される場所をひどく制限します。トップレベルの await にある API から読み込んだり、サービスを呼び出したりしていることを意味します。 ロード時間。 代わりに、消費者が自分のペースで使用できる非同期関数をエクスポートする必要があります。