콜백함수와 제어권
콜백함수란 다른 코드의 인자로 넘겨주는 함수. 이때 콜백함수의 매개변수, 양식, 실행, 호출 시점 등에 대한 모든 제어권은 얘를 인자로 받는 코드가 가짐!! 사용자가 실행시키고 싶을 때 실행할 수 없음!
동기와 비동기 개념
- 동기 synchronous : 현재 실행 중인 코드가 종료돼야만 다음 코드를 실행
- 비동기 asynchronous : 실행 중인 코드의 완료 여부와 무관하게 즉시 다음 코드로 넘어감
별도의 "요청, 실행 대기, 보류" 등의 기능을 갖는 코드는 모두 비동기적인 코드
비동기 작업의 동기적 표현
1. Promise 활용
- Promise는 처리가 끝나면 알려줘~ 하는 약속임.
- new 연산자로 호출한 Promise의 콜백함수는 바로 실행됨
- 콜백함수 내부의 resolve(처리 성공) 또는 reject(처리 실패) 중 하나가 실행되지 전까진 then(다음 처리)이나 catch(오류)로 넘어가지 않음!
/* 예시 */
new Promise(function (resolve) { // new Promise(콜백함수)로 약속 시작
setTimeout(function () {
var name = '에스프레소';
console.log(name);
resolve(name); // resolve 실행 종료돼야만
}, 500);
}).then(function (prevName) { // then 구문 처리 시작!
return new Promise(function (resolve) {
setTimeout(function () {
var name = prevName + ', 아메리카노';
console.log(name);
resolve(name);
}, 500);
});
})
2. Generator 활용
- 제너레이터 함수는 iterator 객체를 반환함. 보통 function뒤에 별표 *가 붙어있다는 특징이 있음
- 여러 개의 값을 필요에 따라 하나씩 반환(yield)할 수 있음. 일반 함수에서 return이 제너레이터에선 yield인 느낌 (제너레이터에서 return은 마아지막 반환하고 함수 끝낼 때 씀)
- next() 메서드를 통해 함수를 실행하면 가장 먼저 만나는 yield의 값을 반환하고, done을 통해 함수 실행이 끝났는지 진행 중인지 알려줌. 근데 반환할 값이 남았는 지 여부로 이해하는 게 쉬운 듯? yield나 return이 남아있으면 done이 되지 않은 거니 false. 싹 다 반환했으면 true
/* 예시 */
var addCoffee = function (prevName, name) {
setTimeout(function () {
coffeeMaker.next(prevName ? prevName + ', ' + name : name);
// 여기서 매 타이머마다 다음 yield 실행!
}, 500);
};
var coffeeGenerator = function* () {
var espresso = yield addCoffee('', '에스프레소');
console.log(espresso);
var americano = yield addCoffee(espresso, '아메리카노');
console.log(americano);
var mocha = yield addCoffee(americano, '카페모카');
console.log(mocha);
var latte = yield addCoffee(mocha, '카페라떼');
console.log(latte);
};
var coffeeMaker = coffeeGenerator();
coffeeMaker.next(); // 여기서 첫 yield 실행!
3. async / await 활용 (+ Promise)
- async가 붙은 함수의 실행로직에서 await를 만나면, await의 처리가 끝날 때까지 기다리는 원리
- 이 때 await와 오는 메서드는 항상 Promise를 반환해야함!
/* 예시 */
var addCoffee = function (name) { // await 마다 실행될 함수
return new Promise(function (resolve) { // Promise를 반환함!
setTimeout(function(){
resolve(name);
}, 500);
});
};
var coffeeMaker = async function () { // async가 붙은 함수, 스코프에서 await 만나면 기다림
var coffeeList = '';
var _addCoffee = async function (name) { // console.log를 위한 함수
coffeeList += (coffeeList ? ', ' : '') + await addCoffee(name);
};
await _addCoffee('에스프레소'); // 첫 await
console.log(coffeeList);
await _addCoffee('아메리카노'); // 다 될 때까지 기다렸다가 두 번째 await
console.log(coffeeList);
await _addCoffee('카페모카'); // 마찬가지
console.log(coffeeList);
await _addCoffee('카페라떼'); // 마찬가지
console.log(coffeeList);
};
coffeeMaker(); // 딸깍 실행
'JS 공부' 카테고리의 다른 글
JS문법종합반 정리 5주차 - DOM, Class, Closure (2) | 2024.11.10 |
---|---|
JS문법종합반 정리 3주차 03 - 콜스택, 실행컨텍스트, VE, LE, 식별자정보, 외부환경정보, 호이스팅, 스코프, this, call(), apply(), bind() (2) | 2024.11.07 |
JS문법종합반 정리 3주차 02 - 객체 복제, 얕은 복사, 깊은 복사 (3) | 2024.11.06 |
JS문법종합반 정리 3주차 01 - 메모리, 기본형 데이터, 참조형 데이터 (0) | 2024.11.06 |
JS문법종합반 정리 2주차 - ES6문법, 일급객체로서 함수, Map, Set (0) | 2024.11.05 |