Notice
Recent Posts
Recent Comments
Link
«   2025/01   »
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
관리 메뉴

개발자공부일기

자바스크립트 기초 문법5 본문

TIL(Today I Learned)

자바스크립트 기초 문법5

JavaCPP 2024. 11. 7. 20:45

콜백지옥 

콜백 지옥(callback hell)이란 비동기 작업이 중첩된 콜백 함수들로 인해 코드의 깊이가 깊어지고 가독성이 떨어지는 현상을 말합니다. 주로 JavaScript에서 비동기 작업(예: 파일 읽기, API 호출, 이벤트 처리 등)을 처리하기 위해 콜백 함수가 반복적으로 사용될 때 발생합니다.  

setTimeout(
  function (name) {
    var coffeeList = name;
    console.log(coffeeList);

    setTimeout(
      function (name) {
        coffeeList += ", " + name;
        console.log(coffeeList);

        setTimeout(
          function (name) {
            coffeeList += ", " + name;
            console.log(coffeeList);

            setTimeout(
              function (name) {
                coffeeList += ", " + name;
                console.log(coffeeList);
              },
              500,
              "카페라떼"
            );
          },
          500,
          "카페모카"
        );
      },
      500,
      "아메리카노"
    );
  },
  500,
  "에스프레소"
);

이런 경우 때문에 자바스크립트에서는 비동기적인 작업을 동기적으로(동기적인 것 처럼 보이도록) 처리해주는 장치를 계속해서 마련해주고 있어요. Promise, Generator(ES6), async/await(ES7)같은 것들이죠

이거 눈으로 따라가며 해석하다 눈운동을 했다.

 

 

비동기작업의 동기적 표현

-Promise

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);
	});
});

Promise는 비동기 처리에 대해, 처리가 끝나면 알려달라는 ‘약속’이에요.

  • new 연산자로 호출한 Promise의 인자로 넘어가는 콜백은 바로 실행돼요.
  • 그 내부의 resolve(또는 reject) 함수를 호출하는 구문이 있을 경우 resolve(또는 reject) 둘 중 하나가 실행되기 전까지는 다음(then), 오류(catch)로 넘어가지 않아요.
  • 따라서, 비동기작업이 완료될 때 비로소 resolve, reject 호출해요.

 

- Generator

*가 붙은 함수가 제너레이터 함수입니다. 제너레이터 함수는 실행하면, Iterator 객체가 반환(next()를 가지고 있음)돼요.

iterator 은 객체는 next 메서드로 순환 할 수 있는 객체구요. next 메서드 호출 시, Generator 함수 내부에서 가장 먼저 등장하는 yield에서 stop 이후 다시 next 메서드를 호출하면 멈췄던 부분 -> 그 다음의 yield까지 실행 후 stop

즉, 비동기 작업이 완료되는 시점마다 next 메서드를 호출해주면 Generator 함수 내부소스가 위 -> 아래 순차적으로 진행돼요 

var addCoffee = function (prevName, name) {
	setTimeout(function () {
		coffeeMaker.next(prevName ? prevName + ', ' + name : name);
	}, 500);
};
var coffeeGenerator = function* () {
	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 + Async/await

ES2017에서 새롭게 추가된 async/await 문을 이용했어요. 비동기 작업을 수행코자 하는 함수 앞에 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);
	};
	await _addCoffee('에스프레소');
	console.log(coffeeList);
	await _addCoffee('아메리카노');
	console.log(coffeeList);
	await _addCoffee('카페모카');
	console.log(coffeeList);
	await _addCoffee('카페라떼');
	console.log(coffeeList);
};
coffeeMaker();

 

코드들을 눈으로 다 따라다니며 해석해보려 했는데 익숙치 않은건지 이해가 안된건지 해석하다 자꾸 길을 잃었다.

이정도 길이에 길을 잃으면 안되는데..? 예시들을 좀 자주 살펴보며 눈에 익혀야겠다. this의 행방이랑 콜백함수에 대해    자꾸 헷갈렸는데 하루종일 찾아보다보니 눈에 익었다. 그리고 Promise라던가 setTimeout같은 함수들의 형태를 몰라서 더 헷갈렸던거 같다. 처음 보는 함수가 생기면 MDN에 쳐보고 오자.