programing

최상위 레벨에서 비동기/대기 기능을 사용하려면 어떻게 해야 합니까?

goodsources 2023. 1. 23. 10:12
반응형

최상위 레벨에서 비동기/대기 기능을 사용하려면 어떻게 해야 합니까?

나는 계속 검토했다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);

콘솔은 다음(노드 v8.6.0)을 출력합니다.

> outside: [객체 약속]

> 내부:거기 안녕.

함수 내부의 로그메시지가 나중에 실행되는 이유는 무엇입니까?는 그 했다.async/await는 비동기 태스크를 사용하여 동기 실행을 수행하기 위해 작성되었습니다.

할 수 ?.then() 후에main()

나는 왜 이것이 작동하지 않는지 이해할 수 없을 것 같다.

★★★★★★★★★★★★★★★★★★mainasync기능에는 문제가 없습니다.

최상위 수준에서는 다음 중 하나를 수행해야 합니다.

  1. 최신 환경에서 광범위하게 지원되고 있는 MDN, MDN, ES2022를 사용하여 다음 기능을 최고 수준으로 사용할 수 있습니다.await듈듈내 。

    또는

  2. 레벨의 「」를 합니다.async('처리되지 않은 거부' 오류를 원하지 않는 한) 거부하지 않는 함수입니다.

    또는

  3. then ★★★★★★★★★★★★★★★★★」catch.

레벨 1 톱 1 1 1await 내에서

하시면 됩니다.await이치노는 약속할 되지 않습니다.awaitsetts(즉, 모듈 로드를 대기하고 있는 모듈은 약속이 정착될 때까지 로드를 완료하지 않습니다).약속이 거부되면 모듈 로드는 실패합니다. 톱 레벨의 「」, 「」await수 전혀 할 수

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

할 수 , 레벨의 "R"을 수 .awaitin a a a a 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예: '커밋').asyncfunction does)는 해당 약속이 정착될 때까지 기다렸다가 해당 약속에 의존하는 모듈의 본문을 평가합니다.

하면 안 요.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; 약속 거부/비동기 예외를 처리해야 합니다.다른 건 아무것도 없기 때문입니다.이 예외는 전달처가 없습니다(위의 #1과는 달리 '비동기'는 모듈로더입니다).필요에 따라서, 콜 한 결과로서 이 작업을 실시할 수 있습니다.catchtry/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그리고 명시적인 약속 콜백)이 아니면 하지 말 것을 권합니다.

또는 물론 오류를 처리하지 않고 "처리되지 않은 거부" 오류를 허용합니다.

#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콜백은 에러를 처리하도록 등록되어 있지 않기 때문에 에러를 슬로우 합니다.

Top-Level이 Stage 3으로 이행했습니다.고객님의 질문에 대한 답변은 "Top Level에서 비동기/대기 사용 방법"입니다.그냥 쓰는 거야await:

const text = await Promise.resolve('Hey there');
console.log('outside: ' + text)

main(): 추가: " "awaitmain():

async function main() {
    var value = await Promise.resolve('Hey there');
    console.log('inside: ' + value);
    return value;
}

var text = await main();  
console.log('outside: ' + text)

호환성.

2021년 답변: 현재 안정적인 버전의 노드에서 최상위 wait를 사용할 수 있습니다.

위의 답변의 대부분은 최신이 아니거나 매우 상세하기 때문에 노드 14 이후의 간단한 예를 제시하겠습니다.

「 」라고 하는 이름의 합니다.runme.mjs:

import * as util from "util";
import { exec as lameExec } from "child_process";
const exec = util.promisify(lameExec);
const log = console.log.bind(console);

// Top level await works now
const { stdout, stderr } = await exec("ls -la");
log("Output:\n", stdout);
log("\n\nErrors:\n", stderr);

실행합니다.node runme.mjs

Output:
 total 20
drwxr-xr-x  2 mike mike 4096 Aug 12 12:05 .
drwxr-xr-x 30 mike mike 4096 Aug 12 11:05 ..
-rw-r--r--  1 mike mike  130 Aug 12 12:01 file.json
-rw-r--r--  1 mike mike  770 Aug 12 12:12 runme.mjs



Errors:

현재 답변에 대한 추가 정보 제공:

★★의 node.js파일은 현재 문자열과 같은 방식으로 연결되며 함수 본문을 형성합니다.

를 파일이 있는 test.js:

// Amazing test file!
console.log('Test!');

★★★★★★★★★★★★★★★.node.js 다음과 연결합니다.

function(require, __dirname, ... perhaps more top-level properties) {
  // Amazing test file!
  console.log('Test!');
}

주의할 점은 결과 함수가 비동기 함수가 아니라는 것입니다. 때문에 이 할 수 없습니다.await★★★★★★★★★★★★★★★★★!

그러나 이 파일의 약속에 대해 작업해야 한다고 가정하면 다음 두 가지 방법이 있습니다.

  1. 마세요await 함수 바로 안쪽
  2. 마세요await

이 스코프는 「1」로 할 수 ).async" " " " " " " 」

// Amazing test file!
// Create a new async function (a new scope) and immediately call it!
(async () => {
  await new Promise(...);
  console.log('Test!');
})();

옵션 2는 객체 지향 약속 API(예쁘지 않지만 동일한 기능을 가진 약속 API)를 사용해야 합니다.

// Amazing test file!
// Create some sort of promise...
let myPromise = new Promise(...);

// Now use the object-oriented API
myPromise.then(() => console.log('Test!'));

에서는 톱레벨의 되어 있는 을 볼 수 .await!

이제 노드 v13.3.0에서 최상위 대기 기능을 사용할 수 있습니다.

import axios from "axios";

const { data } = await axios.get("https://api.namefake.com/");
console.log(data);

을 실행하다--harmony-top-level-await

node --harmony-top-level-await index.js

이 문제에 대한 실제 해결책은 다르게 접근하는 것입니다.

일반적으로 애플리케이션의 최상위 레벨에서 발생하는 일종의 초기화가 목표일 수 있습니다.

해결책은 어플리케이션의 최상위 레벨에1개의 JavaScript 스테이트먼트만 존재하도록 하는 것입니다.어플리케이션의 맨 위에1개의 스테이트먼트만 있는 경우, 그 외의 모든 포인트에서 비동기/대기 기능을 자유롭게 사용할 수 있습니다(물론 통상의 구문 규칙에 따릅니다).

바꿔 말하면, 상위 레벨 전체가 더 이상 상위 레벨이 되지 않도록 함수로 묶어서 애플리케이션의 최상위 레벨에서 비동기/대기 실행 방법에 대한 문제를 해결합니다. 그렇지 않습니다.

어플리케이션의 최상위 레벨은 다음과 같습니다.

import {application} from './server'

application();

노드 -
node --experimental-repl-awaitREP rep rep 、 REP 。대본에 대해서는 잘 모르겠어요.

데노 -
데노에노

다른 솔루션에는 POSIX 컴플라이언스에 관한 중요한 세부 정보가 결여되어 있었습니다.

당신이 해야 할 필요가 있다.

  • 성공 시 0 종료 상태를 보고하고 실패 시 0이 아닌 상태를 보고합니다.
  • 를 발생시키다stderr출력 스트림
#!/usr/bin/env node

async function main() {
 // ... await stuff ... 
}

// POSIX compliant apps should report an exit status
main()
    .then(() => {
        process.exit(0);
    })
    .catch(err => {
        console.error(err); // Writes to stderr
        process.exit(1);
    });

커맨더와 같은 명령줄 파서를 사용하는 경우에는main().

예:

#!/usr/bin/env node

import commander from 'commander'

const program = new commander.Command();

program
  .version("0.0.1")
  .command("some-cmd")
  .arguments("<my-arg1>")
  .action(async (arg1: string) => {
    // run some async action
  });

program.parseAsync(process.argv)
  .then(() => {
    process.exit(0)
  })
  .catch(err => {
    console.error(err.message || err);
    if (err.stack) console.error(err.stack);
    process.exit(1);
  });

나는 진입점에서 비동기 작업을 하기 위한 이 영리한 구문이 좋다.

void async function main() {
  await doSomeWork()
  await doMoreWork()
}()
  1. 패키지에 유형을 추가해야 합니다.json

    "type": "module"
    
  2. 당신은 가도 좋습니다.

    import axios from 'axios';
    const res = await axios.get('https://api.github.com/users/wesbos');
    console.log(res.data);
    

문서 유형을 변경할 경우 ES6 방식으로 코드를 작성해야 합니다.

ECMAScript22에서는await를 참조해 주세요.

다음 예시는 (의 경우)입니다.await) : top top) 、 ) : top ) :

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

(가 없는 다른await를 참조해 주세요.

  async function callApi() {
    const response = await fetch("...");
    console.log(response)      
}
callApi()

[ ]에는 [Browser]를 .type="module"

없이type="module"

<script>
  const resp = await fetch('https://jsonplaceholder.typicode.com/users');
  const users = await resp.json();
  console.log(users)
</script>

type="module"

<!--script type="module" src="await.js" -->
<script type="module">
  const resp = await fetch('https://jsonplaceholder.typicode.com/users');
  const users = await resp.json();
  console.log(users)
</script>

NodeJS 14.8+에서는 최상위 대기 모듈(#3 솔루션)을 사용할 수 있습니다..js의 이름을 .js(.cjs CommonJS)가 아닌 .mjs(ES 모듈)로 변경할 수도 있습니다.

★★main()비동기적으로 실행됩니다.약속을 반환합니다.결과를 가져와야 합니다.then()방법.그리고 왜냐하면then()' 약속도 '반환 약속', '반환 약속', '반환 약속', '반환 약속' 이렇게 요.process.exit()프로그램을 종료합니다.

main()
   .then(
      (text) => { console.log('outside: ' + text) },
      (err)  => { console.log(err) }
   )
   .then(() => { process.exit() } )

언급URL : https://stackoverflow.com/questions/46515764/how-can-i-use-async-await-at-the-top-level

반응형