var count = 0;
var cbFufnc = function() { // 콜백함수
console.log(count);
if (++count > 4) clearInterval(timer);
};
var timer = setInterval(cbFunc, 300);
// -- 실행 결과 --
// 0 (0.3초)
// 1 (0.6초)
// 2 (0.9초)
// 3 (1.2초)
// 4 (1.5초)
code | 호출 주체 | 제어권 |
---|---|---|
cbFunc(); | 사용자 | 사용자 |
setInterval(cbFunc, 300); | setInterval | setInterval |
콜백 함수 예제 (map):
var newArr = [10, 20, 30].map(function (currentValue, index) {
console.log(currentValue, index);
return currentValue + 5;
});
console.log(newArr);
// -- 실행 결과 --
// 10 0
// 20 1
// 30 2
// [15, 25, 35]
위에서 사용한 map 함수는 아래와 같이 콜백 함수로 구성되어 있다.
Array.prototype.map(callback[, thisArg]}
callback: function(currentValue, index, array)
setTimeout(function () {
console.log(this);
}, 300); // (1) Window { ... }
[1, 2, 3, 4, 5].forEach(function (x) {
console.log(this); // (2) Window { ... }
});
document.body.innerHTML += '<button id="a">클릭</button>';
document.body.querySelector("#a").addEventListener("click", function (e) {
console.log(this, e); // (3) <button id="a">클릭</button>
}); // MouseEvent { isTrusted: true, ... }
var obj = {
vals: [1, 2, 3],
logValues: function (v, i) {
console.log(this, v, i);
},
};
obj.logValues(1, 2); // (1) {vals: [1, 2, 3], logValues: f} 1 2
[4, 5, 6].forEach(obj.logValues); // (2) Window {...} 4 0
콜백 함수 내부의 this에 다른값을 바인딩(전통적인 방식):
var obj1 = {
name: "obj1",
func: function () {
var self = this;
return function () {
console.log(self.name);
};
},
};
var callback = obj1.func(); // (1)
setTimeout(callback, 1000); // (2) obj1
콜백 함수 내부에서 this를 사용하지 않을 경우:
var obj1 = {
name: "obj1",
func: function () {
console.log(obj1.name);
},
};
setTimeout(obj1.func, 1000);
ES5의 bind 메서드를 활용해서 바인딩 할 수도 있다:
var obj1 = {
name: "obj1",
func: function () {
console.log(this.name);
},
};
setTimeout(obj1.func.bind(obj1), 1000);
콜백 지옥 예시:
setTimeout(
function (name) {
var coffeeList = name;
console.log(coffeeList);
setTimeout(function (name) {
coffeeList += ", " + name;
console.log(coffeeList);
setTimeout(function (name) {
coffeeList += ", " + name;
console.log(coffeeList);
setTimeout(function (name) {
coffeeList += ", " + name;
console.log(coffeeList);
},500,"에스프레소"
);
},500,"카페라떼"
);
},500,"카페모카"
);
},500,"아메리카노"
);
// 결과:
// 아메리카노
// 아메리카노, 카페모카
// 아메리카노, 카페모카, 카페라떼
// 아메리카노, 카페모카, 카페라떼, 에스프레소
결과:
var coffeeList = "";
var addAmericano = function (name) {
coffeeList += name;
console.log(coffeeList);
setTimeout(addMocha, 500, "카페모카");
};
var addMocha = function (name) {
coffeeList += ", " + name;
console.log(coffeeList);
setTimeout(addLatte, 500, "카페라떼");
};
var addLatte = function (name) {
coffeeList += ", " + name;
console.log(coffeeList);
setTimeout(addEspresso, 500, "에스프레소");
};
var addEspresso= function (name) {
coffeeList += ", " + name;
console.log(coffeeList);
};
setTimeout(addAmericano, 500, '아메리카노');
결과:
1) Promise 예시
var addCoffee = function (name) {
return function (prevName) {
return new Promise(function (resolve) {
setTimeout(function () {
var newName = prevName ? prevNAme + ", " + name : name;
console.log(newName);
resolve(newName);
}, 500);
});
};
};
addCoffee("아메리카노")()
.then(addCoffee("카페모카"))
.then(addCoffee("카페라떼"))
.then(addCoffee("에스프레소"));
2) Generator
var addCoffee = function (prevName, name) {
setTimeout(function () {
coffeeMaker.next(prevName ? prevName + ", " + name : name);
}, 500);
};
var coffeeGenerator = function* () {
var americano = yield addCoffee("", "아메리카노");
console.log(americano);
var mocha = yield addCoffee("", "카페모카");
console.log(mocha);
var latte = yield addCoffee("", "카페라떼");
console.log(latte);
var espresso = yield addCoffee("", "에스프레소");
console.log(espresso);
};
var coffeeMaker = coffeeGenerator();
coffeeMaker.next();
3) Promise + Async/await
var addCoffee = function (name) {
return new Promise(function (resolve) {
setTimeout(function () {
resolve(name);
}, 500);
});
};
var coffeeMaker = async function () {
var coffeeList = "";
var _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();
정재남, 『코어 자바스크립트』, 위키북스(2019), p94-114.