비동기 프로그래밍에서 Generator 사용법 FAQ
Q1: Generator란 무엇인가요?
A1: Generator는 함수 실행을 일시 중지하고 다시 재개할 수 있는 특수한 함수입니다. `function*` 키워드로 정의하며, `yield` 키워드로 값을 내보내고 실행을 중단합니다.
Q2: 비동기 프로그래밍에 왜 Generator를 사용하나요?
A2: 비동기 작업을 동기 코드처럼 순차적으로 작성할 수 있어 콜백 지옥(callback hell)이나 복잡한 Promise 체인을 피할 수 있습니다. Generator가 중단과 재개 기능을 활용하여 비동기 흐름을 제어합니다.
Q3: Generator로 비동기 함수 호출하는 기본 패턴은 무엇인가요?
A3: Generator는 비동기 작업 결과를 기다려야 하므로 일반적으로 `yield` 뒤에 Promise를 반환하는 비동기 함수를 호출합니다. 외부에서 이 Generator를 실행하며 `next()` 호출 시마다 Promise 완료를 기다린 뒤 다음 단계로 진행합니다.
```javascript
function* myAsyncTask() {
const data = yield fetchData(); // fetchData()는 Promise 반환
console.log(data);
}
```
Q4: Generator 기반 비동기 실행 함수를 직접 만들려면 어떻게 하나요?
A4: Promise가 해결될 때마다 Generator의 `next()`를 호출하는 헬퍼 함수를 작성합니다. 예:
```javascript
function run(generatorFunc) {
const gen = generatorFunc();
function step(nextF) {
let next;
try {
next = nextF();
} catch(e) {
return Promise.reject(e);
}
if (next.done) return Promise.resolve(next.value);
return Promise.resolve(next.value).then(
v => step(() => gen.next(v)),
e => step(() => gen.throw(e))
);
}
return step(() => gen.next(undefined));
}
```
Q5: 예시를 보여주세요.
A5:
```javascript
function fetchData() {
return new Promise(resolve => setTimeout(() => resolve('data received'), 1000));
}
function* myAsyncTask() {
const data = yield fetchData();
console.log(data);
}
run(myAsyncTask);
```
Q6: Generator 사용 시 주의할 점은?
A6: 직접 Promise와 Generator 흐름을 잘 연결해야 하며, 에러 처리 메커니즘을 설계해야 합니다. 또한 ES2017 이후에는 `async/await`가 더 간결하고 표준화된 비동기 처리 방법입니다.
Q7: Generator와 async/await의 차이점은 무엇인가요?
A7: async/await는 Generator 위에 문법적 설탕(syntactic sugar)으로 만들어져 더 간편하고 명확합니다. Generator는 낮은 단계의 제어를 가능하게 하지만 코드를 직접 관리해야 하므로 복잡할 수 있습니다.
---
요약하면, Generator 기반 비동기 프로그래밍은 `function*`으로 함수를 정의하고, `yield`로 비동기 작업(Promise)을 대기하며, 실행을 직접 제어하는 헬퍼 함수를 통해 비동기 흐름을 관리하는 방식입니다. 현재는 `async/await`가 일반적입니다.
비동기 프로그래밍은 프로그램이 I/O 작업이나 네트워크 요<a href='https://sangseek.com/sangseeks/청과/ko'>청과</a> 같은 시간이 오래 걸리는 작업을 수행할 때, 다른 작업을 동시에 수행할 수 있도록 해주는 프로그래밍 방식입니다. Python에서는 `asyncio`와 함께 `generator`를 사용하여 비동기 프로그래밍을 구현할 수 있습니다. 이 글에서는 `generator`의 기본 개념과 비동기 프로그래밍에서의 사용법에 대해 자세히 설명하겠습니다. Generator란? Generator는 Python에서 이터레이터를 생성하는 간단한 방법입니다. 일반적인 함수와 달리, generator 함수는 `yield` 키워드를 사용하여 값을 반환합니다. 함수가 호출되면, 실행이 중단되고 `yield`에서 반환된 값이 호출자에게 전달됩니다. 이후 함수가 다시 호출되면, 이전 상태에서부터 실행이 재개됩니다. ```python def simple_generator(): yield 1 yield 2 yield 3 gen = simple_generator() print(next(gen)) 1 print(next(gen)) 2 print(next(gen)) 3 ``` 위의 예제에서 `simple_generator` 함수는 1, 2, 3을 순차적으로 반환합니다. `next()` 함수를 사용하여 generator에서 값을 가져올 수 있습니다. 비동기 프로그래밍에서의 Generator Python의 비동기 프로그래밍에서는 `asyncio` 모듈과 함께 `async def`와 `await` 키워드를 사용하여 <a href='https://sangseek.com/sangseeks/비동기 함수/ko'>비동기 함수</a>를 정의합니다. 하지만 Python 3.5 이전 버전에서는 `generator`를 사용하여 비동기 프로그래밍을 구현할 수 있었습니다. 이 방식은 `yield`를 사용하여 비동기 작업을 수행하고, `yield`가 호출될 때까지 다른 작업을 수행할 수 있게 해줍니다. 비동기 Generator의 예 아래는 비동기 작업을 수행하는 generator의 예입니다. 이 예제에서는 `time.sleep()` 대신 `asyncio.sleep()`을 사용하여 비동기적으로 대기합니다. ```python import asyncio async def async_task(name, delay): print(f"Task {name} started") await asyncio.sleep(delay) print(f"Task {name} completed") async def main(): tasks = [ async_task("A", 2), async_task("B", 1), async_task("C", 3) ] await asyncio.gather(*tasks) asyncio.run()을 사용하여 main() 함수를 실행합니다. asyncio.run(main()) ``` 위의 코드에서 `async_task` 함수는 비동기적으로 실행되는 작업을 정의합니다. `main` 함수는 여러 개의 비동기 작업을 동시에 실행하기 위해 `asyncio.gather()`를 사용합니다. 이 경우, 각 작업은 서로의 완료를 기다리지 않고 동시에 실행됩니다. Generator와 Asyncio의 조합 Python 3.5 이전 버전에서는 `asyncio`와 generator를 조합하여 비동기 프로그래밍을 구현할 수 있었습니다. 아래는 그 예시입니다. ```python import asyncio def generator_task(name, delay): print(f"Task {name} started") yield from asyncio.sleep(delay) print(f"Task {name} completed") def main(): loop = asyncio.get_event_loop() tasks = [ loop.run_in_executor(None, generator_task, "A", 2), loop.run_in_executor(None, generator_task, "B", 1), loop.run_in_executor(None, generator_task, "C", 3) ] loop.run_until_complete(asyncio.gather(*tasks)) main() ``` 위의 예제에서는 `generator_task` 함수를 정의하고, `yield from`을 사용하여 비동기 작업을 수행합니다. `main` 함수에서는 이벤트 루프를 생성하고, 여러 개의 작업을 동시에 실행합니다. 결론 Python에서 비동기 프로그래밍을 구현하는 방법은 여러 가지가 있으며, `generator`는 그 중 하나입니다. `asyncio` 모듈과 함께 사용하면 비동기 작업을 효율적으로 처리할 수 있습니다. Python 3.5 이후 버전에서는 `async`와 `await` 키워드를 사용하여 더 <a href='https://sangseek.com/sangseeks/직관/ko'>직관</a>적이고 간결한 비동기 코드를 작성할 수 있게 되었습니다. 그러나 여전히 `generator`를 사용한 비동기 프로그래밍은 유용한 기술이며, 특히 기존 코드와의 호환성을 유지해야 할 때 유용합니다.