Async/await
"오늘의AI위키"의 AI를 통해 더욱 풍부하고 폭넓은 지식 경험을 누리세요.
1. 개요
`async/await`는 비동기 프로그래밍을 동기 프로그래밍처럼 보이게 해주는 문법적 설탕으로, 여러 프로그래밍 언어에서 지원한다. C#, 파이썬, 자바스크립트, 러스트, C++, 스위프트 등 다양한 언어에서 구현되었으며, 각 언어별로 `async`와 `await` 키워드의 사용법과 구현 방식에 차이가 있다. `async/await`는 비동기 코드의 가독성을 높이고 유지보수를 용이하게 하지만, "함수 색상" 문제와 같은 비판도 존재한다. 한국 개발 생태계에서는 Node.js, Python, 웹 프론트엔드 개발 등 다양한 분야에서 널리 활용되고 있다.
더 읽어볼만한 페이지
- 제어 흐름 - 프로그램 카운터
프로그램 카운터는 CPU 내에서 다음에 실행될 명령어의 주소를 저장하는 레지스터로, 명령어 사이클의 fetch 단계에서 사용되어 명령어를 가져오고 실행 후 갱신되며, CPU 성능 향상 기술과 현대 프로그래밍 모델에 영향을 미친다. - 제어 흐름 - 예외 처리
예외 처리는 프로그램 실행 중 예외 발생 시 정상적인 실행 흐름을 유지하거나 안전하게 종료하기 위한 메커니즘으로, 많은 프로그래밍 언어에서 제공하며 예외 안전성을 목표로 한다. - 프로그래밍 언어 - 다중 패러다임 프로그래밍 언어
다중 패러다임 프로그래밍 언어는 둘 이상의 프로그래밍 패러다임을 지원하며, 다양한 프로그래밍 스타일을 혼합하여 사용할 수 있도록 설계되었다. - 프로그래밍 언어 - 모조 (프로그래밍 언어)
모조는 모듈러사에서 개발한 파이썬과 유사한 구문의 고성능 프로그래밍 언어로, AI 애플리케이션 개발에 초점을 맞추고 러스트의 영향을 받은 메모리 안전성을 제공하며 향후 오픈 소스로 전환될 예정이다.
Async/await | |
---|---|
기능 개요 | |
설명 | 비동기 함수를 작성하는 컴퓨터 프로그래밍 구문. 이를 통해 호출 스레드가 차단되지 않고 다른 작업을 수행할 수 있다. |
역사 및 구현 | |
최초 구현 언어 | C# (Microsoft) |
최초 구현 시기 | 2012년 |
특징 | 비동기 프로그래밍의 어려움을 완화하고 코드를 단순화함. |
지원 언어 | |
지원 언어 목록 | C# 자바스크립트 파이썬 스위프트 러스트 스칼라 님 PHP (8.1 버전부터) 타입스크립트 코틀린 |
2. 역사
F#은 2007년에 비동기 워크플로우를 도입하여 async/await 개념의 초기 형태를 제시했다.[4] 이는 C#의 async/await 메커니즘에 영향을 주었다.[5]
`async`/`await`는 비동기 프로그래밍을 동기 프로그래밍처럼 보이게 하는 문법적 설탕(Syntactic sugar)이다.[58] `async` 키워드는 함수를 비동기 함수로 표시하며, 이 함수는 암시적으로 프로미스(Promise) 또는 퓨처(Future)를 반환한다.[12] `await` 키워드는 비동기 작업의 완료를 기다리는 데 사용되며, 비동기 함수 내에서만 사용할 수 있다. `await`는 프로미스가 완료될 때까지 함수의 실행을 일시 중단하고, 완료되면 결과를 반환하거나 예외를 발생시킨다.
Scala-async에서 `async`는 매크로를 사용하여 구현된다. 컴파일러는 이를 통해 유한 상태 머신 구현을 생성하는데, 이는 모나드 구현보다 효율적이지만 직접 작성하기에는 불편하다.
C#은 2011년에 Async CTP에서 프로토타입 버전이 구현되었고,[43] 2012년 C# 5.0에서 async/await를 정식으로 도입하여 널리 사용되기 시작했다.[6][12]
사이먼 말로우는 2012년에 async 패키지를 개발했다.[7]
파이썬은 2015년 버전 3.5에 `async`와 `await` 키워드를 추가하여 async/await 지원을 추가했다.[8]
타입스크립트는 2015년 버전 1.7에 async/await 지원을 추가했다.[9]
자바스크립트는 2017년에 ECMAScript 2017 자바스크립트 에디션의 일부로 async/await 지원을 추가했다.
러스트는 2019년 버전 1.39.0에 `async` 키워드와 `.await` 후위 연산자를 사용하여 async/await 지원을 추가했는데, 이는 2018 에디션에 도입되었다.[10]
C++는 2020년 버전 20에 `co_return`, `co_await`, `co_yield` 키워드를 사용하여 async/await 지원을 추가했다.
스위프트는 2021년 [https://docs.swift.org/swift-book/LanguageGuide/Concurrency.html 버전 5.5]에 `async`와 `await` 키워드를 추가하여 async/await 지원을 추가했다. 이는 `actor` 키워드를 사용한 액터 모델의 구체적인 구현과 함께 출시되었으며,[11] async/await를 사용하여 외부에서 각 액터에 대한 접근을 중재한다.
3. 개념
다음은 `async`/`await` 패턴을 사용한 C# 함수의 예시이다. 이 함수는 URI에서 리소스를 다운로드하여 리소스의 길이를 반환한다.
```csharp
public async Task
{
var client = new HttpClient();
byte[] data = await client.GetByteArrayAsync(uri);
return data.Length;
}
```
C#의 `async`/`await` 패턴은 컴파일 시간에 람다 또는 연속을 사용하여 구현된다. 예를 들어, 위의 코드는 컴파일러에 의해 다음과 유사한 코드로 변환된다.
```csharp
public Task
{
var client = new HttpClient();
Task
Task
return originalTask.Result.Length;
});
return afterDataTask;
}
```
Python 3.5는 `async`/`await` 지원을 추가했다.
```python
import asyncio
async def main():
print("hello")
await asyncio.sleep(1)
print("world")
asyncio.run(main())
```
JavaScript의 `await` 연산자는 비동기 함수 내에서만 사용할 수 있다.
```javascript
async function createNewDoc() {
const response = await db.post({}); // doc을 전송한다
return await db.get(response.id); // id로 검색한다
}
async function main() {
try {
const doc = await createNewDoc();
console.log(doc);
} catch (err) {
console.log(err);
}
}
main();
```
C++에서는 `await`가 정식으로 C++20 드래프트에 병합되어 C++20의 일부로 정식 수리될 예정이다.[49] 다만, 실제 C++ 키워드는 `await`가 아닌 `co_await`라는 이름이 되었다.
```c++
#include
#include
using namespace std;
future
{
int c = a + b;
co_return c;
}
future
{
int ret = co_await add(1, 2);
cout << "return " << ret << endl;
}
int main()
{
auto fut = test();
fut.wait();
return 0;
}
```
2019년 11월 7일, `async`/`await`가 Rust의 안정 버전에서 사용 가능하게 되었다.[51]
```rust
// futures 크레이트를 사용하기 위해, 크레이트의 Cargo.toml 의존성 섹션에 `futures = "0.3.0"`을 정의해야 한다.
extern crate futures; // 현재, `std` 라이브러리에는 executor 가 존재하지 않는다.
// 다음과 같이 디슈가링된다.
// `fn async_add_one(num: u32) -> impl Future4. 구현
Scala-async는 다양한 비동기 구현을 지원할 계획도 가지고 있다.
4. 1. C#
C#에서 비동기 프로그래밍은 `async` 및 `await` 키워드를 사용하여 구현된다. 이를 통해 개발자는 백그라운드 스레드를 차단하지 않고도 I/O 바운드 또는 CPU 바운드 작업을 수행할 수 있다.
다음은 `async` 및 `await`를 사용하여 URI에서 데이터를 다운로드하고 그 길이를 반환하는 C# 메서드(함수)의 예시이다.
```csharp
public async Task
{
var client = new HttpClient();
byte[] data = await client.GetByteArrayAsync(uri);
return data.Length;
}
```
`async` 메서드는 `void`, `Task`, `Task
C#의 async/await 패턴은 컴파일 시간에 람다 또는 연속을 사용하여 구현되므로, 실제로는 런타임의 핵심 부분이 아니다. 컴파일러는 async/await 코드를 상태 머신으로 변환하여 비동기 작업을 효율적으로 처리한다.
4. 2. F#
F#은 2007년 버전 2.0에서 비동기 워크플로우를 추가했다.[14] 비동기 워크플로우는 CE(계산식)로 구현된다. C#의 `async`와 같은 특별한 컨텍스트를 지정하지 않고 정의할 수 있다. F# 비동기 워크플로우는 비동기 작업을 시작하기 위해 키워드에 느낌표(!)를 추가한다.[42]
다음은 비동기 워크플로우를 사용하여 URL에서 데이터를 다운로드하는 비동기 함수 예시이다.
```f#
let asyncSumPageSizes (uris: #seq
use httpClient = new HttpClient()
let! pages =
uris
|> Seq.map(httpClient.GetStringAsync >> Async.AwaitTask)
|> Async.Parallel
return pages |> Seq.fold (fun accumulator current -> current.Length + accumulator) 0
}
4. 3. 파이썬
파이썬 3.5(2015)[19]는 유리 셀리바노프(Yury Selivanov)가 작성하고 구현한 PEP 492에 설명된 async/await에 대한 지원을 추가했다.[20]
```python
import asyncio
async def main():
print("hello")
await asyncio.sleep(1)
print("world")
asyncio.run(main())
```
Python영어 3.5는 async/await 지원을 추가했다. 더 자세한 내용은 PEP0492 (https://www.python.org/dev/peps/pep-0492/)를 참조하라.
```python
import asyncio
async def main():
print("hello")
await asyncio.sleep(1)
print("world")
asyncio.run(main())
4. 4. 자바스크립트
JavaScript에서 `await` 연산자는 비동기 함수 내부 또는 모듈의 최상위 레벨에서만 사용할 수 있다. 매개변수가 프라미스인 경우, 프라미스가 해결되면 비동기 함수의 실행이 재개된다. (프라미스가 거부된 경우에는 일반적인 JavaScript 예외 처리로 처리할 수 있는 오류가 발생한다). 매개변수가 프라미스가 아닌 경우, 매개변수 자체가 즉시 반환된다.[21]
많은 라이브러리에서 `await`와 함께 사용할 수 있는 프라미스 객체를 제공하며, 네이티브 JavaScript 프라미스에 대한 사양과 일치하는 경우이다. 그러나 jQuery 라이브러리의 프라미스는 jQuery 3.0까지 Promises/A+ 호환이 되지 않았다.[22]
다음은 예시이다. (이[23] 기사에서 수정됨):
```javascript
async function createNewDoc() {
let response = await db.post({}); // 새 문서를 게시합니다.
return db.get(response.id); // ID로 찾기
}
async function main() {
try {
let doc = await createNewDoc();
console.log(doc);
} catch (err) {
console.log(err);
}
}
main();
```
Node.js 버전 8에는 표준 라이브러리 콜백 기반 메서드를 프라미스로 사용할 수 있게 해주는 유틸리티가 포함되어 있다.[24]
아래 코드는 위와 동일한 예시이다. (이 문서[47]에서 일부 변경):
```javascript
async function createNewDoc() {
const response = await db.post({}); // doc을 전송한다
return await db.get(response.id); // id로 검색한다
}
async function main() {
try {
const doc = await createNewDoc();
console.log(doc);
} catch (err) {
console.log(err);
}
}
main();
```
(예시) 전통적인 콜백 코딩 | async/await 패턴 코딩 |
---|---|
4. 5. 러스트
rust// futures 크레이트를 사용하기 위해, 크레이트의 Cargo.toml 의존성 섹션에 `futures = "0.3.0"`을 정의해야 한다.
extern crate futures; // 현재, `std` 라이브러리에는 executor 가 존재하지 않는다.
// 다음과 같이 디슈가링된다.
// `fn async_add_one(num: u32) -> impl Future
5. 장점 및 비판
`async`/`await` 패턴은 자체 런타임을 가지고 있지 않거나 제어하지 않는 언어의 언어 설계자들에게 특히 매력적인데, 컴파일러에서 상태 머신으로 변환하는 것만으로 구현될 수 있기 때문이다.[34]
`async`/`await` 패턴을 지원하는 언어의 큰 장점은 비동기, 논블로킹 코드를 최소한의 오버헤드로 작성할 수 있으며, 기존의 동기 블로킹 코드와 거의 동일하게 보인다는 것이다. 이러한 애플리케이션은 그래픽 사용자 인터페이스를 제공하는 프로그램부터 게임, 금융 애플리케이션 등 매우 확장 가능한 상태 저장 서버 측 프로그램에 이르기까지 다양하다.
5. 1. 장점
`async`/`await`는 비동기 코드를 마치 동기 코드처럼 작성할 수 있게 해주어 코드의 가독성과 유지보수성을 크게 향상시킨다. 이는 복잡한 콜백 함수(Callback Hell)의 사용을 줄여 코드의 복잡성을 낮추고, 개발자가 비동기 프로그래밍을 더 쉽게 이해하고 사용할 수 있도록 돕는다.[35]특히, `await`는 메시지 전달 프로그램에서 비동기 코드를 작성하는 가장 좋은 방법으로 꼽히며, 기존의 동기 블로킹 코드와 유사한 형태로 작성할 수 있다는 점, 가독성이 높고, 코드의 양을 최소화할 수 있다는 장점이 있다.[52]
C#, JavaScript 등 많은 프로그래밍 언어에서 `async`/`await` 패턴을 지원하며, 이를 통해 개발자는 비동기 프로그래밍을 더욱 효율적으로 수행할 수 있다. 예를 들어, C#에서는 `async` 키워드를 사용하여 메서드를 비동기적으로 선언하고, `await` 키워드를 사용하여 비동기 작업의 완료를 기다릴 수 있다.
```csharp
public async Task
{
var client = new HttpClient();
byte[] data = await client.GetByteArrayAsync(uri);
return data.Length;
}
```
위 코드에서 `await` 키워드는 `GetByteArrayAsync` 메서드가 완료될 때까지 기다린 후, 다음 코드를 실행한다. 이처럼 `async`/`await`를 사용하면 비동기 코드를 동기 코드처럼 작성할 수 있어 코드의 가독성이 높아진다.
결과적으로, `async`/`await`는 프로그램의 성능을 향상시키는 동시에, 개발자가 코드를 더 쉽게 이해하고 관리할 수 있도록 돕는 강력한 도구이다.
5. 2. 비판
`async`/`await` 비판자들은 이 패턴이 주변 코드도 비동기적으로 만드는 경향이 있고, 그 전염성으로 인해 언어의 라이브러리 생태계가 동기 및 비동기 라이브러리와 API로 분리되는 경향이 있다고 지적하며, 이 문제를 종종 "함수 색상"이라고 부른다.[36] 이 문제를 겪지 않는 `async`/`await`의 대안을 "무색"이라고 부른다. 무색 설계의 예로는 Go의 고루틴과 Java의 가상 스레드가 있다.[37]`await`가 비판받을 때에는, `await`가 주변 코드도 비동기적으로 만드는 경향이 있다는 점이 종종 지적된다. 한편, 이 코드의 전염성("좀비 바이러스"에 비유되기도 함)은 모든 종류의 비동기 프로그래밍에 고유하다고 주장되어 왔기 때문에, 이 점에 관해서는 `await`에만 특유한 것은 아니다.[53]
6. 한국 개발 생태계
async/await 패턴은 Node.js를 이용한 백엔드 개발에서 활발하게 사용되고 있다. 자바스크립트를 기반으로 한 Node.js 환경에서는 비동기 처리가 필수적이기 때문이다.
Python의 asyncio를 이용한 비동기 프로그래밍도 점차 증가하는 추세이다. 웹 프론트엔드 개발에서도 API 호출 등 비동기 처리를 위해 async/await를 적극적으로 활용하고 있다.
다음은 전통적인 콜백 코딩과 async/await 패턴 코딩을 비교한 예시이다.
전통적인 콜백 코딩 | async/await 패턴 코딩 |
---|---|
참조
[1]
웹사이트
Announcing Rust 1.39.0
https://blog.rust-la[...]
2019-11-07
[2]
웹사이트
Version 0.9.4 released - Nim blog
https://nim-lang.org[...]
2020-01-19
[3]
웹사이트
Concurrency — The Swift Programming Language (Swift 5.5)
https://docs.swift.o[...]
2021-09-28
[4]
서적
Practical Aspects of Declarative Languages
Springer Link
2021-04-29
[5]
웹사이트
The Early History of F#, HOPL IV
https://dl.acm.org/t[...]
2021-04-29
[6]
웹사이트
Anders Hejlsberg: Introducing Async – Simplifying Asynchronous Programming
https://channel9.msd[...]
Microsoft
2021-01-05
[7]
웹사이트
async: Run IO operations asynchronously and wait for their results
https://hackage.hask[...]
[8]
웹사이트
What's New In Python 3.5 — Python 3.9.1 documentation
https://docs.python.[...]
2021-01-05
[9]
웹사이트
Announcing TypeScript 1.7
https://devblogs.mic[...]
Microsoft
2015-11-30
[10]
웹사이트
Async-await on stable Rust! {{!}} Rust Blog
https://blog.rust-la[...]
Rust Blog
2021-01-05
[11]
웹사이트
Concurrency — the Swift Programming Language (Swift 5.6)
https://docs.swift.o[...]
[12]
서적
C# in Depth
Manning
2019-03-23
[13]
서적
C# 10 in a Nutshell
O'Reilly
2022
[14]
웹사이트
Introducing F# Asynchronous Workflows
https://blogs.msdn.m[...]
2007-10-10
[15]
웹사이트
Task-based asynchronous pattern
https://docs.microso[...]
Microsoft
2020-09-28
[16]
서적
C# 8.0 and .NET Core 3.0 – Modern Cross-Platform Development: Build Applications with C#, .NET Core, Entity Framework Core, ASP.NET Core, and ML.NET Using Visual Studio Code
Packt
2022
[17]
웹사이트
Extending the async methods in C#
https://devblogs.mic[...]
2022-10-30
[18]
문서
Async/Await - Best Practices in Asynchronous Programming
https://msdn.microso[...]
Stephen Cleary
[19]
웹사이트
Python Release Python 3.5.0
https://www.python.o[...]
[20]
웹사이트
PEP 492 – Coroutines with async and await syntax
https://www.python.o[...]
[21]
웹사이트
await - JavaScript (MDN)
https://developer.mo[...]
2017-05-02
[22]
웹사이트
jQuery Core 3.0 Upgrade Guide
https://jquery.com/u[...]
2017-05-02
[23]
웹사이트
Taming the asynchronous beast with ES7
http://pouchdb.com/2[...]
2015-11-12
[24]
웹사이트
Node v8.0.0 (Current) - Node.js
https://nodejs.org/e[...]
2017-05-30
[25]
웹사이트
ISO C++ Committee announces that C++20 design is now feature complete
https://hub.packtpub[...]
2019-02-25
[26]
웹사이트
Coroutines (C++20)
https://en.cpprefere[...]
[27]
웹사이트
s_task - awaitable coroutine library for C
https://github.com/x[...]
[28]
웹사이트
Future::AsyncAwait - deferred subroutine syntax for futures
https://metacpan.org[...]
[29]
웹사이트
September 2018 Grant Votes - The Perl Foundation
http://news.perlfoun[...]
2019-03-26
[30]
웹사이트
Async-await on stable Rust!
https://blog.rust-la[...]
2019-11-07
[31]
웹사이트
Async/Await
https://os.phil-opp.[...]
2020-10-28
[32]
웹사이트
Archived copy
https://www.swift.or[...]
2021-12-20
[33]
웹사이트
SE-0296
https://github.com/a[...]
[34]
웹사이트
Async Part 3 - How the C# compiler implements async functions
https://www.awise.us[...]
[35]
간행물
Eight ways to handle non-blocking returns in message-passing programs
http://ithare.com/ei[...]
'No Bugs'' Hare'
2018
[36]
웹사이트
What Color is Your Function?
https://journal.stuf[...]
[37]
웹사이트
Virtual Threads
https://docs.oracle.[...]
[38]
웹사이트
Announcing Rust 1.39.0
https://blog.rust-la[...]
2019-11-07
[39]
웹사이트
Version 0.9.4 released - Nim blog
https://nim-lang.org[...]
2020-01-19
[40]
웹사이트
Scala Async
https://github.com/s[...]
2013-10-20
[41]
문서
".NETにおいて、Task
を返すメソッドの名前は、慣例的にAsync
の接尾辞が付けられる。"
[42]
웹사이트
Introducing F# Asynchronous Workflows
https://blogs.msdn.m[...]
2020-06-05
[43]
웹사이트
Asynchrony in C# 5, Part One
https://docs.microso[...]
2021-04-18
[44]
간행물
Async/Await - Best Practices in Asynchronous Programming
https://msdn.microso[...]
Stephen Cleary
[45]
웹사이트
await - JavaScript (MDN)
https://developer.mo[...]
2017-05-02
[46]
웹사이트
jQuery Core 3.0 Upgrade Guide
http://jquery.com/up[...]
2017-05-02
[47]
웹사이트
Taming the asynchronous beast with ES7
http://pouchdb.com/2[...]
2015-11-12
[48]
웹사이트
Node v8.0.0 (Current) - Node.js
https://nodejs.org/e[...]
2020-06-05
[49]
웹사이트
ISO C++ Committee announces that C++20 design is now feature complete
https://hub.packtpub[...]
2020-06-05
[50]
웹사이트
September 2018 Grant Votes - The Perl Foundation
http://news.perlfoun[...]
2019-03-26
[51]
웹사이트
Async-await on stable Rust!
https://blog.rust-la[...]
2019-11-07
[52]
간행물
Eight ways to handle non-blocking returns in message-passing programs
http://ithare.com/ei[...]
'No Bugs' Hare
[53]
간행물
Async/Await - Best Practices in Asynchronous Programming
https://msdn.microso[...]
Stephen Cleary
[54]
웹인용
Announcing Rust 1.39.0
https://blog.rust-la[...]
2019-11-07
[55]
웹인용
Version 0.9.4 released - Nim blog
https://nim-lang.org[...]
2020-01-19
[56]
웹인용
Scala Async
https://github.com/s[...]
2013-10-20
[57]
웹인용
Concurrency — The Swift Programming Language (Swift 5.5)
https://docs.swift.o[...]
2021-09-28
[58]
웹인용
Async-await on stable Rust!
https://blog.rust-la[...]
2019-11-07
[59]
웹인용
Async/Await
https://os.phil-opp.[...]
2020-10-28
본 사이트는 AI가 위키백과와 뉴스 기사,정부 간행물,학술 논문등을 바탕으로 정보를 가공하여 제공하는 백과사전형 서비스입니다.
모든 문서는 AI에 의해 자동 생성되며, CC BY-SA 4.0 라이선스에 따라 이용할 수 있습니다.
하지만, 위키백과나 뉴스 기사 자체에 오류, 부정확한 정보, 또는 가짜 뉴스가 포함될 수 있으며, AI는 이러한 내용을 완벽하게 걸러내지 못할 수 있습니다.
따라서 제공되는 정보에 일부 오류나 편향이 있을 수 있으므로, 중요한 정보는 반드시 다른 출처를 통해 교차 검증하시기 바랍니다.
문의하기 : help@durumis.com