최상위 레벨에서 비동기/대기 기능을 사용하려면 어떻게 해야 합니까?
나는 계속 검토했다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()
나는 왜 이것이 작동하지 않는지 이해할 수 없을 것 같다.
★★★★★★★★★★★★★★★★★★main
async
기능에는 문제가 없습니다.
최상위 수준에서는 다음 중 하나를 수행해야 합니다.
최신 환경에서 광범위하게 지원되고 있는 MDN, MDN, ES2022를 사용하여 다음 기능을 최고 수준으로 사용할 수 있습니다.
await
듈듈내 。또는
레벨의 「」를 합니다.
async
('처리되지 않은 거부' 오류를 원하지 않는 한) 거부하지 않는 함수입니다.또는
then
★★★★★★★★★★★★★★★★★」catch
.
레벨 1 톱 1 1 1await
내에서
하시면 됩니다.await
이치노는 약속할 되지 않습니다.await
setts(즉, 모듈 로드를 대기하고 있는 모듈은 약속이 정착될 때까지 로드를 완료하지 않습니다).약속이 거부되면 모듈 로드는 실패합니다. 톱 레벨의 「」, 「」await
수 전혀 할 수
const text = await main();
console.log(text);
할 수 , 레벨의 "R"을 수 .await
in 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
예: '커밋').async
function 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과는 달리 '비동기'는 모듈로더입니다).필요에 따라서, 콜 한 결과로서 이 작업을 실시할 수 있습니다.catch
try
/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()
: 추가: " "await
의 main()
:
async function main() {
var value = await Promise.resolve('Hey there');
console.log('inside: ' + value);
return value;
}
var text = await main();
console.log('outside: ' + text)
호환성.
- v8은 2019년 10월 이후
- 플래그 뒤의 노드 v13.3+
--harmony-top-level-await
- TypeScript 3.8+ (문제)
- 2019년 10월 이후 Deno
- Webpack@v5.0.0-alpha.15
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
★★★★★★★★★★★★★★★★★!
그러나 이 파일의 약속에 대해 작업해야 한다고 가정하면 다음 두 가지 방법이 있습니다.
- 마세요
await
함수 바로 안쪽 - 마세요
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-await
REP 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()
}()
패키지에 유형을 추가해야 합니다.json
"type": "module"
당신은 가도 좋습니다.
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
'programing' 카테고리의 다른 글
Mysql: 테이블에서 다른 테이블에 없는 행을 선택합니다. (0) | 2023.01.23 |
---|---|
Jhipster에서 JDL을 사용할 때 오류 발생 (0) | 2023.01.23 |
ID 필드별로 Vuex에 저장된 개체 배열에서 항목을 가져오려면 어떻게 해야 합니까? (0) | 2023.01.23 |
jQuery를 사용하여 이름으로 요소를 선택하려면 어떻게 해야 합니까? (0) | 2023.01.23 |
JavaScript에서 문자열 배열을 대소문자를 구분하지 않고 정렬하려면 어떻게 해야 합니까? (0) | 2023.01.23 |