javascript 4주차

정태수·2025년 2월 10일

콜백 함수 - 다른 함수의 인자로 넘겨주는 함수

제어권을 넘겨줄테니 너가 알고있는 로직으로 처리해줘.

  1. setTimeout : n초 후 값 출력해줘
  2. forEach: 반복하다 맞는 로직대로 처리해줘.

제어권

1. 호출 시점 setInterval

//콜백 함수

var count = 0;

var Func = function() {
    console.log('count:', count);
    if(count > 4) clearInterval(timer)
}

//만약 
Func();
//이렇게 호출한다면 함수는 한번 호출되고 끝날 것 즉 호출 주체가 나임.
//하지만
var timer = setInterval(Func, 300);
//이렇게 호출한다면 호출 주체는 제어권을 가지고 있는 setInterval 함수이다.

2. 인자에 대한 제어권

var newArr = [10, 20, 30].map(function(currentValue, index) {
        console.log(currentValue, index)
        return currentValue + 5;
})

console.log(newArr)

//여기서 만약 currentValue, index 순서이지만 만약 둘이 바꾸면 컴퓨터는 index를 값으로 인식한다.
//정해진 규칙대로 사용해야한다.
//인자에 대한 제어권이 함수에게 있다.

3. this

콜백 함수도 함수이기에 this는 전역객체이다.
예외사항이 있는데

제어권을 넘겨받을 코드에서 콜백 함수에 별도로 this가 될 대상을 지정한 경우. (week3)

함수마다 다른데 함수 구현 내부동작에 this를 따로 지정해놓은 함수가 있고 아닌게 있다.

var obj = {
    vals: [1,2,3],
    logValues : function (v,i) {
        if(this === global) {
            console.log('this is global')
        } else {
            console.log(this, v, i);
        }

    }
}

//method로서 호출
// obj.logValues(1,2)

var arr = [4,5,6]
//메서드로서 호출했을때 객체(obj)바인딩이 되는거다
//인자로 들어갔을때는 전역객체를 this로 본다.
arr.forEach(obj.logValues)

콜백지옥과 비동기 제어

계속된 함수의 인자로 쓰여지는 콜백함수들에 의해 코드이 들여쓰기 수준이 헬 수준인 경우.
가독성이 매우 안좋다
주로 서버통신 코드와 비동기 처리할때

들여쓰기로 인해 가독성이 안좋다는게 확 와닿는다.

해결법1. 기명함수

결과는 같은데 단번에 어떻게 실행되는지 알수있음.

Promise

비동기 처리에 대해 처리가 끝나면 알려달라는 약속
new 연산자로 호출한 Promise의 인자로 넘어가는 콜백은 바로 실행됨.
그 내부의 resolve 또는 reject 함수를 호출하는 구문이 있을 경우 resolve, reject 둘중 하나가 실행되기 전까지는 then 이나 catch로 넘어가지 않는다.
따라서, 비동기 작업이 종료되엇을 때 비로소 reslove, reject 호출.

따라서, 비동기작업이 완료될 때 비로소 resolve, reject 호출
우리는 이 방법으로 비동기 -> 동기적 표현을 구현할 수 있음.

new Promise(function (resolve) {
	setTimeout(function () {
		var name = '에스프레소';
		console.log(name);
		resolve(name);
	}, 500);
}).then(function (prevName) {
	return new Promise(function (resolve) {
		setTimeout(function () {
			var name = prevName + ', 아메리카노';
			console.log(name);
			resolve(name);
		}, 500);
	});
}).then(function (prevName) {
	return new Promise(function (resolve) {
		setTimeout(function () {
			var name = prevName + ', 카페모카';
			console.log(name);
			resolve(name);
		}, 500);
	});
}).then(function (prevName) {
	return new Promise(function (resolve) {
		setTimeout(function () {
			var name = prevName + ', 카페라떼';
			console.log(name);
			resolve(name);
		}, 500);
	});
});

리팩토링 이후

var addCoffee = function (name) {
    return function(prevName) {
        //이 안에서도 새로운 Promise!
        console.log('firstFuc:', prevName)
        return new Promise(function(resolve){
            setTimeout(function(){
                //
                var newName = prevName ? prevName + name : name;
                console.log(newName);
                resolve(newName);
            }, 500)
        })
    }
}

var addCoffeeArrowVersion = (name) => {
    return function(prevName) {
        //이 안에서도 새로운 Promise!
        console.log('firstFuc:', 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('dsadsad'))

Generator

profile
프론트엔드 개발자

0개의 댓글