JS 4주차 정리 :: 콜백함수 | 동기 & 비동기 | promise | 제네레이터 및 | async await

728x90
반응형

1. 콜백함수_기본개념

- 다른 코드의 인자로 넘겨주는 함수 / 인자로 넘겨주는 다는 것은 받는 곳이 있음 

- forEach, setTimeout : 콜백함수를 적절한 시점에 실행하게 됨 (제어권이 forEach,setTime에게 있음)

- 내일 약속이 있는데 알람 안 맞추고, 수시로 일어나서 시간 확인 하는 스폰지밥 (제어권 : 스폰지밥)

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

//콜백함수 예시1
setTimeout(function () {
	 console.log("hello");
},1000);

//콜백함수 예시2
const num = [1,2,3,4,5];
num.forEach(function (num) {
	console.log(num);
});

 

2. 콜백함수_제어권1

- 제어권은 호출시점

//무슨 제어권?
//1. 호출 시점에 대한 제어권을 갖음
//setInterval(); 고정된 시간 지연으로 반복적으로 수행

let count = 0;
let timer = setInterval(function(){
            console.log(count);
            if(++count>4) clearInterval(timer); 
},300); //0.3초 제어권을 setInterval이 갖음

3. 콜백함수_제어권2

- 인자에 대한 제어권을 갖음 (Map함수)

- 사용방법 순서 그대로 사용해야한다 --> currentValue,index 이런것

//2. 제어권 두번째
//map : 새로운 배열 생성

let newArr = [10,20,30].map(function(currentValue, index) {
	console.log(currentValue, index); //10 0 , 20 1 ,30 2
    return currentValue + 5; //map은 return문 필수 ! [15,25,35]
});


//콜백함수 순서 바꾸기-- index <-> currentValue
//currentValue,index = 사람이 이해할 수 있는 값일 뿐, 컴퓨터는 자리수를 인식함

let newArr = [10,20,30].map(function(index,currentValue) {
	console.log(index, currentValue); //10 0 , 20 1 ,30 2
    return currentValue + 5; //[5,6,7]--> 인덱스에 +5가 됨
});

4. 콜백함수_this 바인딩

- 기본적으로 this는 전역객체를 참조함 (setTimeout / forEach --> global 객체)

> 예외 : addEventListener (부모를 상속함: this =  document.body.querySeletor('#a')) 이렇게 설계가 됨

//이렇게 배열처럼 사용하기 가능
// Array.prototype.map123
Array.prototype.map123 = function() {
	console.log("hello");	
}

[1,2,3].map123(); // hello 


//map함수는 인자로 callback, this를 받음 (내부 this와 구분되게 thisArg로 설정)
// 새로운 배열 리턴
Array.prototype.map123 = function(callback, thisArg) {
	//map 함수에서 return할 결과배열
    var mappedArr = [];
    
    for( let i =0; i< this.length; i++){
    //this의 주체는 호출 [1,2,3].map123()-> length : 3
     	let mappedValue = callback.call(thisArg || global, this[i]); //콜백함수 수행-> call 즉시 수행
    															     //값이 있으면 thisArg, 없으면 global, this[i]값
           mappedArr[i] = mappedValue;                                                     
    }
    return mappedArr;
};

let newArr = [1,2,3].map123(function(num){
	return num*2 ;
}); // [2,4,6]

 

5. 콜백함수_객체의 메서드 전달시 this

- 함수여서 전역객체를 바라보게 됨

- 명시적으로 바인딩 : call, apply, bind / self 변수= 할당하기

- 원하는 this를 얻을 수 없었음 > 6강에서 할 것

 

6. 콜백함수_내부 this에 다른 값 바인딩

- 클로저 : 현재의 함수가 끝났음에도 불구하고 영향력을 끼친다 > 5주차에 학습

- bind를 함수를 만들어 놓을 때 유용함 

//bind (추천)
let obj1 = {
	name: "obj1",
    func: function() {
		console.log(this.name); //this는 무조건 obj1이됨
  	}
}

// setTimeout (function(){},1000)-> 새로운 함수 만들어주기
setTimeout(obj1.func.bind(obj1),1000); //bind(this)=> this =obj1객체를 넣어서
									   //obj1객체가 this로 묶이게 됨
                                       

//함수 자체를 바인딩
//원하는대로 바인드 가능
let obj2 = {name: "obj2"};
setTimeout(obj1.func.bind(obj2),1000);  //name: obj2 출력됨
let obj1 ={
 name: "obj1",
 func: function(){
 	let self = this; //이 부분!
    return function(){
  		console.log(self.name);  //클로저와 관련된 부분
    };	
 }
}

//let callback = obj1.fun(); 아래와 같음
let callback = function(){
	console.log(self.name);
}

//setTimeout(callback,1000); 아래와 같음
setTimeout(function(){
	console.log(self.name);
},1000);


//xxxx
//객체 obj1와 동일한 코드
//결과만을 위한 코딩 => 하드코딩임 10/100점 짜리 코딩 -> 하지마셈
let obj1 ={
 name: "obj1",
 func: function(){
  		console.log(self.name);  //클로저와 관련된 부분
    };	
 }
}

setTimeout(obj1.func,1000);

 

 

7. 콜백함수_콜백지옥과 동기 비동기의 개념 및 예시

- 콜백지옥: 익명함수 (매개변수로 들어가다보니) --> 가독성과 유지보수에서 어려움

 

- [카페]

* 동기

: 한 손님에게 주문+ 커피주기까지 끝 > 다음 손님 받음 (계속 기다림)

: 일의 순서가 중요함

 

* 비동기

: 주문 한번에 받고 진동벨 울리면 찾으로 오셈~  (setTimeout, addEventListner)

: 요청, 실행 대기, 보류 모두 비동기 (+ 통신)

 

8. 콜백함수_promise

- 비동기 작업 : 순서를 보장하지 않음 (제어권이 언제 나한테 올지 모름)

- 비동기처리를 동기적인 것 처럼 작업가능 : promise, generator, async/await

- promise : 비동기처리에 대해, 처리가 끝나면 알려달라는 약속

- new연산자로 호출한 promise의 인자로 넘어가는 콜백--> 바로 실행

- resolve(성공) / reject(실패) : 함수 호출 구문이 있음

//new Promise(function(){}.then (function(){})
new Promise(function (resolve){
	setTimeout(function(){
    	let name = "에스프레소"
        console.log(name);
        resolve(name); //name: 에스프레소
    },500);
}.then(function(prevName){
	// 이 안에서도 새롭게 promise를 만듦
    return new Promise (function (resolve){
	setTimeout(function(){
    	let name = prevName + ", 아메리카노" // prevName(에스프레소)를 붙여줌
        console.log(name); 
        resolve(name); //name: 에스프레소, 아메리카노
    },500);
})

9. 콜백함수_promise 리팩토링

- 다시 구조화 하기 

- 화살표 함수도 가능

let addCoffee = function(name){
return function (prevName){
	//이 안에서도 새롭게 promise를 만들기!
    return new Promise( function(resolve){
	    setTimeout(function(){
    
    	//`(백틱) : 문자열 지정 가능 
    	//let name = prevName +',' + name
        let newName =prevName ? `${prevName}, ${name}` : name;
        console.log(newName);
        resolve(newName); 
        
    },500);
   }
}


addCoffee("에스프레소")()
  .then(addCoffee("아메리카노"))
  .then(addCoffee("카페라떼"));

 

10. 콜백함수_제네레이터 및 async await

- 제네레이터: 반복할 수 있는 이터러블 객체 생성

- 이터러블 객체

: next 메서드 갖고 있음 

: yield (양보하다, 미루다) > 비동기작업의 동기표현 

: 비동기가 완료되는 시점마다, next메서드 호출해서 위>아래로 순차적으로 작업 가능

//비동기적인 요소를 동기적으로 하려는 이유: 순서를 보장할 수 없으니, 순서 보장을 위하여
//function* : *가 있으면 제네레이터 임


let addCoffee = function(prevName,name){
	setTimeout(function(){
    	coffeeMaker.next(prevName ? `${prevName}, ${name}` : name);
    },500);
}

let coffeeGenerator = function*{
	let espresso = yield addCoffee("","에스프레소");       //yield로 스탑을 걸어주는 느낌
    let americano = yield addCoffee(espresso,"아메리카노");
    let latte = yield addCoffee(americano,"카페라떼");
    
}

let coffeeMaker = coffeeGenerator();
coffeeMaker.next();


//promise -> then
//async(비동기) -> await(기다리다)


//coffeeMaker 함수에서 호출할 함수, 'addCoffee'를선언
//promise 반환
let addCoffee = function(name){
    return new Promise( function(resolve){
	    setTimeout(function(){
        resolve(name); 
    },500);
   });
};


let coffeeMaker = async function{
	
    let coffeList = "";
    let _addCoffee = async function(name){
    	coffeList += (coffeeList ?"," : "") + (await addCoffee(name));
    };
    
    //promise를 반환하는 함수의 경우, await를 만나면 무조건 끝날때까지 기다려야함
    await _addCoffee("에스프레소");
    await _addCoffee("아메리카노");
    await _addCoffee("카페라떼");
};

coffeeMaker();

 

끝.

 

 

 

[출처]

1. 스파르타 코딩, JavaScript 문법 종합반 4주차 (1강-10강)

반응형