ES6에서 도입된 제너레이터는 코드 블록의 실행을 일시 중지했다가 필요한 시점에 재개할 수 있는 특수한 함수이다.
제너레이터 함수는 함수 호출자에게 함수 실행의 제어권을 양도할 수 있다. 즉, 함수 호출자가 함수 실행을 일시 중지시키거나 재개시킬 수 있다. 함수의 제어권을 함수가 독점하는 것이 아니라 함수 호출자에게 양도할 수 있다.
제너레이터 함수는 함수 호출자와 함수의 상태를 주고 받을 수 있다.
제너레이터 함수를 호출하면 제너레이터 객체를 반환한다.
제너레이터 함수는 function*
키워드로 선언한다.
그리고 하나 이상의 yield
표현식을 포함한다.
function* genDecFunc() {
yield 1;
}
제너레이터 함수를 호출하면 일반 함수처럼 함수 코드 블록을 실행하는 것이 아니라 제너레이터 객체를 생성해 반환한다.
제너레이터 객체는 next 메서드를 갖는 이터레이터이지만 이터레이터에는 없는 return, throw
메서드를 갖는다.
next 메서드를 호출하면 yield
표현식까지의 코드 블록을 실행하고 yield
된 값을 value 프로퍼티 값으로, false를 done
프로퍼티 값으로 갖는 이터레이터 리절트 객체를 반환한다.
return
메서드를 호출하면 인수로 전달받은 프로퍼티 값으로 를 프로퍼티 값으로 갖는 이터레이터 리절트 객체를 반환한다
function* genDecFunc() {
try {
yield 1;
yield 2;
yield 3;
} catch (e) {
console.error(e);
}
}
const generator = genDecFunc();
console.log(generator.next());
console.log(generator.return('end'));
ES8에서는 async/await
가 도입되었다.
async/await
는 프로미스를 기반으로 동작한다.
async function fetchTodo() {
const url = 'https://jsonplaceholder.typicode.com/todos/1';
const response = await fetch(url);
const todo = await response.json();
console.log(todo);
}
await
키워드는 반드시 async
함수 내부에서 사용해야 한다. 언제나 프로미스를 반환한다.
await
키워드는 프로미스가 settled
상태가 될 때까지 대기하다가 settled
상태가 되면 프로미스가 resolve
한 처리 결과를 반환한다. await
는 반드시 프로미스 앞에서 사용해야 한다.
async/await
에서는 try catch 문을 사용할 수 있다.
const foo = async () => {
try {
const wrongUrl = 'https://wrong.url';
const response = await fetch(wrongUrl);
const data = await response.json();
console.log(data);
} catch (err) {
console.error(err);
}
};