-
Generator와 비동기처리Web Dev/1. JS 문법 관련 2021. 6. 2. 10:12728x90
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을 쓰자.
'Web Dev > 1. JS 문법 관련' 카테고리의 다른 글
JavaScript modules, defer, async 메모 (0) 2021.08.31 제너레이터와 프로미스, Generator와 Promise (0) 2021.06.14 Object.assign() - 열거가능한 모든 프로퍼티 복사 (0) 2021.05.21 ES6의 스코프 (0) 2021.05.20 Modules (0) 2021.05.19