코어 자바스크립트 4장: 콜백함수

송나은·2021년 6월 7일
1

JavaScript

목록 보기
20/23

콜백함수

다른 코드에게 인자를 넘겨줌으로써 그 제어권도 함께 위임한 함수

콜백함수의 특징

  • 콜백함수를 호출할 때 인자로 넘겨줄 값들 및 그 순서가 정해져있다.
  • 콜백함수의 this가 무엇을 바라보도록 할 지 정해져있거나 전역객체를 바라본다. -> 임의로 this를 바꾸고 싶은 경우, bind 메서드를 활용한다.
  • 어떤 함수에 인자로 메서드를 전달하더라도 이는 결국 함수로서 실행된다.
  • 비동기 제어를 위해 콜백함수를 사용하다가 콜백지옥에 빠질 수 있는데, ES6 이후 Promise, Generator, Async/await로 비동기의 동기적 표현을 할 수 있다.

ex) map함수

method 대상이 되는 배열의 모든 요소들을 처음부터 끝까지 하나씩 꺼내 콜백 함수를 반복 호출하고, 콜백함수의 실행 결과들을 모아 새로운 배열을 만든다.

Array.prototype.map(callback[, thisArg])
callback: function(currentValue. index, array)

콜백함수는 함수다

어떤 함수에 인자로 메서드를 전달하더라도 이는 결국 함수로서 실행된다.

var obj = {
  vals: [1, 2, 3],
  logValues: function (v, i) {
  console.log(this, v, i);
  }
};
obj.logValues(1, 2); // { vals: [ 1, 2, 3 ], logValues: ƒ logValues() } 1 2

[4, 5, 6].forEach(obj.logValues) 
/*
Window { ... } 4 0
Window { ... } 5 1
Window { ... } 6 2
*/

동기 vs 비동기

동기

현재 실행중인 코드가 완료된 후에야 다음 코드를 실행하는 방식.
ex) 즉시 처리가 가능한 코드

비동기

현재 실행 중인 코드의 완료 여부와 무관하게 즉시 다음 코드로 넘어가는 방식.
ex) 별도의 요청, 실행 대기, 보류와 관련된 코드

Ajax(=Asynchronouse JavaScript and XML)

자바스크립트를 이용해서 비동기적으로 서버와 브라우저가 데이터를 교환할 수 있는 통신방식.

페이지 전체를 로드하여 렌더링할 필요가 없고 갱신이 필요한 일부만 로드하여 빠르고 부드러운 화면 표시 효과를 기대할 수 있다.

비동기 작업의 동기적 표현방법

1. Promise (ES6)

new 연산자와 함께 호출한 Promise의 인자로 넘겨주는 콜백함수는 호출할 때 바로 실행되지만, 그 내부에 resolve 또는 reject 함수를 호출하는 구문이 있을 경우 둘 중 하나가 실행되기 전까지는 다음(then) 또는 오류구문(catch)으로 넘어가지 않는다.

비동기 작업이 완료될 때 resolve나 reject를 호출한다.

catch (예외 처리)

Promise.resolve()
.then(()=>{
  throw new Erroe('some error');
})
.catch(error => {
  console.log(error);
});

catch, then 모두 promise를 반환하기 때문에 catch 이후에도 then을 사용할 수 있다.

finally

promise 체인의 가장 마지막에 사용된다. 새로운 promise를 생성하지 않기 때문에, promise의 데이터를 건드리지 않고 추가 작업을 할 때 사용할 수 있다.

2. Generator (ES6)

function* 함수 실행 시 Iterator가 반환된다. Iterator는 next라는 method를 가지고 있으며, next 호출 시 Genertor 함수 내부에서 가장 먼저 등장하는 yield에서 함수 실행을 멈춘다.

비동기 작업이 완료되는 시점마다 next method를 호출한다.

const addCoffee = function (prevName, name) {
  setTimeout(function () {
    coffeeMaker.next(prevName ? `${prevName}, ${name}` : name);
  }, 500); // 5초 간격으로 실행
};
const  coffeeGenerator = function* () {
  const  espresso = yield addCoffee('', '에스프레소');
  console.log(espresso);
  const  americano = yield addCoffee(espresso, '아메리카노');
  console.log(americano);
  const  mocha = yield addCoffee(americano, '카페모카');
  console.log(americano);
  const  latte = yield addCoffee(mocha, '카페라떼');
  console.log(americano)
  ;
  
/*
'에스프레소'
'에스프레소, 아메리카노'
'에스프레소, 아메리카노, 카페모카'
'에스프레소, 아메리카노, 카페모카, 카페라떼'
*/

3. Async/await (ES2017)

비동기 작업을 수행하고자 하는 함수 앞에 async를 표기하고 함수 내부에서 실질적인 비동기 작업이 필요한 위치마다 await를 표기하는 것만으로 뒤의 내용을 promise로 자동전환하고 해당 내용이 resolve된 이후에야 다음으로 진행한다.

promise의 then과 흡사한 효과를 얻을 수 있다.

Promise vs Async/await

function getDataPromise() {
  asyncFunc1()
  .then(data => {
    console.log(data);
    return asyncFunc2();
  })
  .then(data => {
    console.log(data);
  });
}
async function getDataAsync() {
  const data1 = await asyncFunc1();
  console.log(data1);
  const data2 = await asyncfunc2();
  console.lod(data2);
}

예외처리

async function getData() {
  try {
    await doAsync();
    return doSync();
  } catch (error) {
    console.log(error);
  }
}

Reference

코어자바스크립트 / 정재남

profile
그때그때 공부한 내용과 생각을 기록하는 블로그입니다.

0개의 댓글