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강)
'JavaScript' 카테고리의 다른 글
바닐라 자바스크립트 SPA (0) | 2023.11.08 |
---|---|
JS 5주차 정리 :: DOM | 클래스 | getters setters 개념 | 클래스 상속 | 클로저 (0) | 2023.10.17 |
JS 3주차 정리 :: 호이스팅 | 실행컨텍스트 | record | this | 콜백함수 | call, apply,bind (0) | 2023.10.16 |
JS 3주차 정리 :: 메모리 | 데이터 할당 | 불변객체 (얕은복사 & 깊은복사) (1) | 2023.10.13 |
JS 2주차 정리 :: ES6 문법 8가지 (구조분해할당, ...전개구문) | 일급객체 | Map | Set (1) | 2023.10.13 |