ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Generator와 비동기처리
    Web Dev/1. JS 문법 관련 2021. 6. 2. 10:12
    728x90

    redux saga를 사용하다보니 내부가 다 Generator였다. 대강 어떻게 굴러가는진 알겠지만 Generator와 Promise가 처리되는 흐름이 영 매끄럽게 이해가 되지 않아서 Modern JavaScript Deepdive 46장을 읽어보았다. 

     

     

    제너레이터란

    function* test(array) {    
        for(let i = 0; i < array.length; i++){
        	yield array[i]
        }
    }
    
    const getArray = test([1,2,3,4,5])
    
    getArray.next();
    getArray.next();
    getArray.next();
    getArray.next();
    getArray.next();
    getArray.next();

     

    이렇게 나온다. 제너레이터 함수를 호출하면 함수를 실행하고 끝나는게 아니라, yield키워드 가 있는데서 값을 반환한다. 그리고 제어권을 호출자에게 줘버린다. 즉, 호출자가 필요할때 .next()를 통해서 다음 동작을 재개할수있게 된다. 

     

     

    제너레이터로 비동기 처리하기

    async/await 키워드가 나타나기전에 제너레이터로 비동기처리를 하셨던것 같다. 

    제너레이터 함수 내에서 Promise가 있는 부분에서 일단 yield를해서 제어권을 함수를 호출한 애한테 준다음, 거기서 Promise가 resolve되면 next()를 하라고 코드를 짜면 된다. 

     

    const async = generatorFunc => {
    	const gen = generatorFunc();
        
        const onResolved = arg => {
        	const result = gen.next(arg); console.log("result", result);
            if(result.done) {
            	return result.done
            }else if(typeof result.value?.then === 'function'){
           		result.value.then(res => onResolved(res))
            }else{
                onResolved(result.value)
            }
        }
        return onResolved;
    }
    
    (async(function* fetchTodo() {
    	const response = yield new Promise((resolve) => setTimeout(() => resolve("test"), 1000));
        const todo = yield response; 
        const test = yield 3; 
        })())
        

    결과가 이렇다. Promise일때는 resolve되고나서 next를 호출하고, promise 아닌건 그냥 호출한다.

    .next()에 넘겨주는 값이 yield 부분 좌측의 변수에 할당이 된다.  그 원리를 이용해서 Promise 객체 인경우, Resolve됬을때 값을 보내서 fetchTodo에서 값을 받아볼수 있도록 만들수가 있다. 

     

    async await을 쓰자. 

     

     

     

    댓글

Designed by Tistory.