코어 자바스크립트 책을 읽고 배운 내용을 바탕으로 작성되었다.
callback function
let intervalID = setInterval(func, [delay, arg1, arg2, ...]);
clearInterval()
을 호출하여 취소할 수 있다.setInterval
에게 있고 콜백함수 호출 시점에 대한 제어권을 가진다.Array.prototype.map(callback[, thisArg])
callback: function(currentValue, index, array)
setTimeout
: 콜백함수 내부의 this가 전역객체를 가리킴.forEach
: 별도의 인자로 this를 넘겨주면 그 대상을 가리킴.addEventListener
: 콜백함수 내부의 this가 호출주체를 가리킴.const obj1 = {
name: 'obj1',
func: function(){
const self = this;
return function(){
console.log(self.name);
};
}
};
const callback = obj1.func();
setTimeout(callback, 1000);
const obj1 = {
name: 'obj1',
func: function(){
console.log(this.name);
}
};
setTimeout(obj1.func.bind(obj1), 1000);
const obj2 = {name: 'obj2'};
setTimeout(obj1.func.bind(obj2), 1500);
asynchronous vs synchronous
setTimeout
)addEventListener
)XMLHttpRequest
)console.log("1st");
setTimeout(() => {
console.log("2nd");
}, 0)
console.log("3rd");
call stack
이 하나인 것을 의미한다.Web APIs
(비동기 메소드), Callback Queue
, Event Loop
를 가지고 있기 때문에 자바스크립트 언어가 비동기적으로 실행될 수 있다.function getData() {
var tableData;
$.get('https://domain.com/products/1', function (response) {
tableData = response;
});
return tableData;
}
console.log(getData()); // undefined
function getData(callbackFunc) {
$.get('https://domain.com/products/1', function(response) {
callbackFunc(response);
});
}
getData(function(tableData) {
console.log(tableData);
});
callback hell
setTimeout(
function (name) {
let coffeeList = name;
console.log(name);
setTimeout(
function (name) {
coffeeList += ", " + name;
console.log(name);
setTimeout(
function (name) {
coffeeList += ", " + name;
console.log(name);
setTimeout(
function (name) {
coffeeList += ", " + name;
console.log(name);
},
500,
"카페라떼"
);
},
500,
"카페모카"
);
},
500,
"아메리카노"
);
},
500,
"에스프레소"
);
// 에스프레소
// 에스프레소, 아메리카노
// 에스프레소, 아메리카노, 카페모카
// 에스프레소, 아메리카노, 카페모카, 카페라떼
let coffeeList = "";
const addEspresso = function (name) {
coffeeList = name;
console.log(coffeeList);
setTimeout(addAmericano, 500, "아메리카노");
};
const addAmericano = function (name) {
coffeeList += ", " + name;
console.log(coffeeList);
setTimeout(addMocha, 500, "카페모카");
};
const addMocha = function (name) {
coffeeList += ", " + name;
console.log(coffeeList);
setTimeout(addLatte, 500, "카페라떼");
};
const addLatte = function (name) {
coffeeList += ", " + name;
console.log(coffeeList);
};
setTimeout(addEspresso, 500, "에스프레소");
new Promise(function(resolve){
setTimeout(function(){
const name = "에스프레소";
console.log(name);
resolve();
}, 500);
}).then(function(prevName){
return new Promise(function(resolve){
setTimeout(function(){
const name = prevName + ', ' + "아메리카노";
console.log(name);
resolve(name);
}, 500);
});
}).then(function(prevName){
return new Promise(function(resolve){
setTimeout(function(){
const name = prevName + ', ' + "카페모카";
console.log(name);
resolve(name);
}, 500);
});
}).then(function(prevName){
return new Promise(function(resolve){
setTimeout(function(){
const name = prevName + ', ' + "카페라떼";
console.log(name);
resolve(name);
}, 500);
});
});
new
연산자와 함께 생성된 Promise의 인자로 넘긴 콜백함수 내부에서 resolve
또는 reject
함수를 호출한다.then
또는 catch
메서드로 넘어간다.resolve
또는 reject
를 호출함으로써 비동기 작업의 동기적 표현이 가능하다.const addCoffee = function(prevName, name){
setTimeout(function(){
coffeeMaker.next(prevName? prevName + ', ' + name: name);
}, 500);
}
const coffeeGenerator = function* () {
const expresso = yield addCoffee('', "에스프레소");
console.log(expresso);
const americano = yield addCoffee(expresso, "아메리카노");
console.log(americano);
const mocha = yield addCoffee(americano, "카페모카");
console.log(mocha);
const latte = yield addCoffee(mocha, "카페라떼);
console.log(latte);
}
const coffeeMaker = coffeeGenerator();
coffeeMaker.next();
const addCoffee = function(name){
return new Promise(function(resolve){
setTimeout(function(){
resolve(name);
}, 500);
});
}
const coffeeMaker = async function(){
let coffeeList = '';
const _addCoffee = async function(name){
coffeeList += coffeeList ? ', ': '' + await addCoffee(name);
}
await _addCoffee("에스프레소");
console.log(coffeeList);
await _addCoffee("아메리카노");
console.log(coffeeList);
await _addCoffee("카페모카");
console.log(coffeeList);
await _addCoffee("카페라떼");
console.log(coffeeList);
}
coffeeMaker();
async
키워드를 붙이고, 함수 내부에서 실질적인 비동기 함수/메서드 앞에 await
키워드를 붙인다.Promise
, Generator
, async/await
등 콜백 지옥에서 벗어날 수 있는 방법들을 제공한다.참고