最初のモジュールには条件付きの戻りパラメーターがあり、2番目のモジュールを実行または終了させるため、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の問題 のように、これがなぜなのかについて、標準化委員会による議論がいくつかあります。
Githubの考え方 トップレベルの待機が悪い考えである理由についてもあります。具体的には、次のようなコードがある場合は次のように提案します。
// data.js
const data = await fetch( '/data.json' );
export default data;
これで、anydata.js
をインポートするファイルは、フェッチが完了するまで実行されないため、すべてのモジュールのロードがブロックされます。これは、トップレベルのJavaScriptを同期的かつ予測可能に実行するために使用されているため、アプリモジュールの順序について推論することを非常に困難にします。これが許可された場合、関数がいつ定義されるかを知るのは難しくなります。
私のパースペクティブは、モジュールをロードするだけで副作用があるのは悪い習慣だということです。つまり、モジュールを要求するだけで、モジュールの消費者は副作用を被ることになります。これにより、モジュールを使用できる場所が大きく制限されます。最上位のawait
は、おそらく、ロード時にAPIから読み込んでいるか、サービスを呼び出していることを意味します。代わりに、非同期でエクスポートする必要があります消費者が自分のペースで使用できる機能。
もちろん、これは常にあります:
(async () => {
await ...
})();
これにより、awaitを使用できるasyncのクイック機能が作成されます。これにより、非同期関数を作成する必要がなくなります。 //クレジットSilve2611
さらに良いのは、コードブロックの前にセミコロンを追加することです
;(async () => {
await ...
})();
これにより、最初の括弧が前の行の末尾に移動する自動フォーマッター(vscodeなど)が防止されます。
この問題は、次の例で実証できます。
const add = x => y => x+y
const increment = add(1)
(async () => {
await ...
})();
セミコロンなしでは、これは次のように再フォーマットされます。
const add = x => y => x+y
const increment = add(1)(async () => {
await Promise(1)
})()
これは明らかに間違っています。非同期関数をy
パラメーターとして割り当て、結果から関数を呼び出そうとするためです(実際には奇妙な文字列'1async () => {...}'
)