콜백에서 Future와 코루틴으로

매일 공부(ML)·2023년 5월 30일
0

Fluent Python

목록 보기
129/130

제어 흐름

asyncio를 이용한 동시성

콜백에서 Future와 코루틴으로

콜백지옥은 어떤 연산이 다른 연산에 종속적일 때, 콜백 안에 콜백이 들어가는 것을 말하고, 차례대로 발생해야 하는 비동기 호출이 세 개 있을 때는 자바스크립트 코드에서 보는 것처럼 세 단계의 콜백을 구현한다.

api_call1(request1, function(response1) {
	// 1단계
    var request2 = step1(response1);
    
    api_call2(request2, function (reponse2) {
    // 2단계
   		var request 3 = step2(response2);
        
        api_call3(request3, function (response3) {
        	// 3단계
            step 3(response3)'
        

api_call1(), api_call2(), api_call3()는 결과를 비동기식으로 가져오기 위해 사용하는 라이브러리 함수로, 각 라이브러리 함수는 콜백 함수를 받고 응답 처리를 하는 일반적인 함수를 나타난다.


#파이썬에서 콜백 지옥
def stage1(response1):
	request2 = step1(response1)
    api_call2(request2, stage2)
    
def stage2(response2):
	request3 = step2(response2)
    api_call3(request3, stage3)
    
def stage3(response3):
	step(response3)
api_call1(request1, stage1)

세 개의 비동기 작업을 연속으로 처리하기 위해서 코루틴 체인에서 yield를 세 번 사용해서 이벤트 루프가 계속 실행할 수 있게 하여, 결과가 나오면 코루틴의 send() 메서드를 호출해서 코루틴을 활성화하면 된다.
이벤트 루프의 관점에서 보면 send() 메서드 호출과 콜백 메서드 호출은 비슷하지만 코루틴 스타일의 비동기 API를 사용하는 입장에서 보면 상황은 더 좋고, 하나의 함수 안에서 전체 작업의 콘텍스트를 지역 변수 안에 넣고, 일반적인 함수를 호출하듯이 연속으로 세 개의 함수를 호출하면 된다.

@asyncio.coroutine
def three_stages(request1):
	response1 = yield form api_call1(request1)
    #1단계
    request2 = step1(response1)
    response2 = yield from api_call2(request2)
    #2단계
    request3 = step2response2
    response3 = yield from api_call3(request3)
    #3단계
    step3(response3)

loop.create_task(three_stages(request1)) #명시적으로 실행을 스케쥴    

코루틴은 천국이 아니다.

첫 번째 장애물: 일반 함수 대신 반드시 코루틴을 사용해야 하고, yield from 에 익숙해져아 한다.

profile
성장을 도울 아카이빙 블로그

0개의 댓글