[javascript] 비동기 함수 외부에서 await 사용

첫 번째에는 두 번째가 모듈을 실행하거나 종료하도록하는 조건부 반환 매개 변수가 있기 때문에 두 개의 비동기 함수를 함께 연결하려고했습니다. 그러나 사양에서 찾을 수없는 이상한 동작을 발견했습니다.

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있지만 특정 세부 사항이없는 유형 오류가 발생했습니다.

수없는 이유는 당신 기능의 범위의 기능 밖에? 나는 그것이 설탕 약속이라는 것을 압니다. 그래서 그것은 연결 되어야만합니다. 그러나 그것은 왜 내가 다른 약속을 기다릴 수 있지만 밖에서는 할 수없는 이유 입니까?awaitasyncthencountPlayerawait isInLobby



답변

최상위 수준 await은 지원되지 않습니다. 이 Github 문제 와 같은 이유에 대한 표준위원회의 몇 가지 토론 있습니다.

Github 에는 최상위 수준이 왜 나쁜 생각인지에 대한 생각이 있습니다. 특히 그는 다음과 같은 코드가있는 경우 다음과 같이 제안합니다.

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

이제 가져 오는 파일은 가져 오기 가 완료 될 때까지 실행되지 않으므로 이제 모든data.js 모듈로드가 차단됩니다. 이것은 우리가 동기적이고 예측 가능한 최상위 자바 스크립트 실행에 익숙하기 때문에 앱 모듈 순서를 추론하기 매우 어렵게 만듭니다. 이것이 허용되면 함수가 언제 정의되는지 아는 것이 까다로워집니다.

내 관점 은 모듈을로드하는 것만으로도 부작용이 발생하는 것은 나쁜 습관이라는 것입니다. 즉, 모듈의 모든 소비자는 단순히 모듈을 요구함으로써 부작용을 얻을 수 있습니다. 이것은 모듈을 사용할 수있는 위치를 심하게 제한합니다. 최상위 수준은 await아마도 일부 API에서 읽거나 로드시 일부 서비스를 호출하고 있음을 의미합니다 . 대신 소비자가 자신의 속도로 사용할 수있는 비동기 함수를 내 보내야합니다.


답변

물론 이것은 항상 있습니다 :

(async () => {
    await ...

    // all of the script.... 

})();
// nothing else

이것은 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 () => {...}')


답변

Node.js 14.3.0 부터 최상위 await가 지원됩니다.

필수 플래그 : --experimental-top-level-await.

추가 정보 : https://v8.dev/features/top-level-await


답변

typescript 3.8부터 최상위 수준 대기를 수행 할 수 있습니다.
https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-8.html#-top-level-await
게시물에서 :
이전에 JavaScript (비슷한 기능을 가진 대부분의 다른 언어와 함께), await는 비동기 함수의 본문 내에서만 허용되었습니다. 그러나 최상위 수준의 await를 사용하면 모듈의 최상위 수준에서 await를 사용할 수 있습니다.

const response = await fetch("...");
const greeting = await response.text();
console.log(greeting);

// Make sure we're a module
export {};

미묘한 점이 있습니다. 최상위 수준 대기는 모듈의 최상위 수준에서만 작동하며 파일은 TypeScript가 가져 오기 또는 내보내기를 찾을 때만 모듈로 간주됩니다. 일부 기본 경우에는이를 확인하기 위해 일부 상용구로 export {}를 작성해야 할 수 있습니다.

이 시점에서 예상 할 수있는 모든 환경에서 최상위 수준 대기가 작동하지 않을 수 있습니다. 현재는 대상 컴파일러 옵션이 es2017 이상이고 모듈이 esnext 또는 system 인 경우에만 최상위 수준 await를 사용할 수 있습니다. 여러 환경 및 번 들러 내에서 지원이 제한되거나 실험적 지원을 활성화해야 할 수 있습니다.


답변