Notice
Recent Posts
Recent Comments
Link
«   2025/03   »
1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31
Tags
more
Archives
Today
Total
관리 메뉴

juni

콜백함수 본문

CS

콜백함수

juni_shin 2024. 4. 30. 22:29
//콜백 함수 -> 다른 코드의 인자로 넘겨주는 함수
// setTimeout(function () {
//     console.log("hi")
// },1000)

const numbers = [1, 2, 3, 4, 5];
numbers.forEach(function (number) {
  console.log(number);
});

//제어권 / 호출 시점에대한 제어권을 갖는다.
//setInterval() : 반복해서 매개변수로 받은 콜백함수의 로직을 수행
let conut = 0;
let cbFunc = function () {
  console.log(conut);
  if (++conut > 4) clearInterval(timer);
};
//setInterval의 반복을 멈추기위한 timer 선언
let timer = setInterval(cbFunc, 300);

// 인자에대한 제어권을 갖는다
// map함수 : 배열에대한 api(메서드) -> 배열에대한 하나하나를 로직에의해 순회하고 가공하여 새로운 배열을 return
let newArr = [10, 20, 30].map(function (currentValue, index) {
  console.log(currentValue, index);
  return currentValue + 5;
});
console.log(newArr);

 

// setTimeout은 내부에서 콜백 함수를 호출할 때, call 메서드의 첫 번째 인자에
// 전역객체를 넘겨요
// 따라서 콜백 함수 내부에서의 this가 전역객체를 가리켜요
setTimeout(function () {
  console.log(this);
}, 300); // Window { ... }

// forEach도 마찬가지로, 콜백 뒷 부분에 this를 명시해주지 않으면 전역객체를 넘겨요!
// 만약 명시한다면 해당 객체를 넘기긴 해요!
[1, 2, 3, 4, 5].forEach(function (x) {
  console.log(this); // Window { ... }
});

//addEventListener는 내부에서 콜백 함수를 호출할 때, call 메서드의 첫 번째
//인자에 addEventListener메서드의 this를 그대로 넘겨주도록 정의돼 있어요(상속)
// document.body.innerHTML += '<button id="a">클릭</button';
// document.body.querySelector("#a").addEventListener("click", function (e) {
//   console.log(this, e); // this가 부모 객체 -> document.body.querySelector 를 가리킴
// });

Array.prototype.map123 = function (callback, thisArg) {
  //맵 함수 인자값 callback함수와 this ->무조건
  //map 함수에서 return할 결과 배열
  let mappedArr = [];

  for (var i = 0; i < this.length; i++) {
    // call의 첫 번째 인자는 thisArg가 존재하는 경우는 그 객체, 없으면 전역객체
    // call의 두 번째 인자는 this가 배열일 것(호출의 주체가 배열)이므로,
    // i번째 요소를 넣어서 인자로 전달
    var mappedValue = callback.call(thisArg || global, this[i]);
    mappedArr[i] = mappedValue;
  }
  return mappedArr;
};

const newArr = [1, 2, 3].map123((item) => {
  return item * 2;
});

console.log(newArr);
let obj = {
  vals: [1, 2, 3],
  logValues: function (v, i) {
    if (this === global) {
      console.log("this->global");
    } else {
      console.log(this, v, i);
    }
  },
};
//method로써 호출은 호출만 하는거임
// ->obj.logValues(1, 2);

//forEach , map , filter : 2개의 매개변수 중 첫번째는 기준이되는 배열의 n번째요소(4) , 인덱스로는 그 요소의 인덱스 (logValues)
// logValues()는 실행한 결과값이 들어가므로 함수를 매개변수로(콜백함수)사용시 함수 자체를 넣어야함
[4, 5, 6].forEach(obj.logValues);

 

//콜백 함수 내부의 this에 다른 값 바인딩하기

// var obj1 = {
//   name: "obj1",
//   func: function () {
//     var self = this; //이 부분!
//     return function () {
//       console.log(self.name);
//     };
//   },
// };

// // 단순히 함수만 전달한 것이기 때문에, obj1 객체와는 상관이 없어요.
// // 메서드가 아닌 함수로서 호출한 것과 동일하죠.
// var callback = obj1.func();
// setTimeout(callback, 1000);

// 결과만을 위한 하드코딩 -> 최대한 지양해야하는 코딩임
// var obj1 = {
//   name: "obj1",
//   func: function () {
//     console.log(obj1.name);
//   },
// };
// setTimeout(obj1.func, 1000);

//제대로 시작
var obj1 = {
  name: "obj1",
  func: function () {
    var self = this; //이 부분!
    return function () {
      console.log(self.name);
    };
  },
};

var obj2 = {
  name: "obj2",
  func: obj1.func,
};

var callback2 = obj2.func();
setTimeout(callback2, 1500);

//원활한 this binding 방법
var obj3 = { name: "obj3" };
var callback3 = obj1.func.call(obj3);
setTimeout(callback3, 2000);

 

// bind : this를 바인딩해서 새로운 함수를 return -> 함수를 만들어 놓을 때 유용
var obj1 = {
  name: "obj1",
  func: function () {
    console.log(this.name);
  },
};
// let boundObj1 = obj1.func.bind(obj1);
// setTimeout(boundObj1, 1000); // obj1 객체가 this로 묶이면서 5번째 줄 this가 무조건 obj1이 된다

//함수 자체를 바인딩 하는 방법
let obj2 = { name: "obj2" };
setTimeout(obj1.func.bind(obj2), 1500); // 원하는대로 새로운 this를 바인딩함

 

// new 연산자로 호출한 Promise의 인자로 넘어가는 콜백은 바로 실행
// 그 내부의 resolve(or reject) 함수를 호출하는 구문이 있을 시
// -> 둘 중 하나가 실행되기 전까지는 다음(then) , 오류(catch)로 진행x
// 비동기작업 완료시 비로소 resolve , reject 호출

new Promise(function (resolve) {
  setTimeout(function () {
    let name = "espreso";
    console.log(name);
    resolve(name);
  }, 500);
})
  .then(function (prevName) {
    //내부에서도 새로운 Promise를 생성
    return new Promise(function (resolve) {
      setTimeout(function () {
        let name = "americano";
        console.log(name);
        resolve(name);
      }, 500);
    });
  })
  .then(function (prevName) {
    //내부에서도 새로운 Promise를 생성
    return new Promise(function (resolve) {
      setTimeout(function () {
        let name = "cafeMocha";
        console.log(name);
        resolve(name);
      }, 500);
    });
  });

 

//비동기화 refectoring (효율화)
let addCoffee = (name) => {
  return function (prevName) {
    //내부에서도 새로운 Promise를 생성
    return new Promise(function (resolve) {
      setTimeout(function () {
        //백틱 , if문 등 활용
        let newName = prevName ? `${prevName}, ${name}` : name;
        console.log(newName);
        resolve(newName);
      }, 500);
    });
  };
};

addCoffee("espreso")() // Promise 리턴을 위해 () 를 추가
  .then(addCoffee("americasno"))
  .then(addCoffee("cafemocha"))
  .then(addCoffee("cafelatte"));

 

var addCoffee = function (prevName, name) {
  setTimeout(function () {
    coffeeMaker.next(prevName ? prevName + ", " + name : name);
  }, 500);
};
// 함수* -> 제너레이터 함수 : 실행시 Iterator 객체가 반환
var coffeeGenerator = function* () {
  //yield 키워드 만날시 멈추고 addcoffee가 끝날때까지 기다렷다가 next메서드 호출시 진행 -> addcoffee내부에 next메서드 로직 존재
  //yield 키워드로 순서 제어
  var espresso = yield addCoffee("", "에스프레소");
  console.log(espresso);
  var americano = yield addCoffee(espresso, "아메리카노");
  console.log(americano);
  var mocha = yield addCoffee(americano, "카페모카");
  console.log(mocha);
  var latte = yield addCoffee(mocha, "카페라떼");
  console.log(latte);
};
//이터레이터 는 넥스트 메서드로 순회가능
var coffeeMaker = coffeeGenerator();
coffeeMaker.next();

 

//Promise : then / 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));
  };
  //promise를 반환하는 함수인경우, await를 만나면 무조건 끝날때까지 대기
  await _addCoffee("에스프레소");
  console.log(coffeeList);
  await _addCoffee("아메리카노");
  console.log(coffeeList);
  await _addCoffee("카페모카");
  console.log(coffeeList);
  await _addCoffee("카페라떼");
  console.log(coffeeList);
};
coffeeMaker();

'CS' 카테고리의 다른 글

JS 문법 복습 및 React 학습  (0) 2024.05.13
JS 문법 복습  (0) 2024.05.12
JS 문법 복습  (0) 2024.05.10
State , Props , useRef , Hooks  (0) 2024.05.06
호이스팅, this  (0) 2024.04.29