JavaScript

개인 과제를 하던 도중 비동기를 구현 할 줄 몰라서 비동기에 대해 다시 공부했다...

추운날_너를_기다리며 2024. 8. 21. 20:26

현재 가장 필요한 비동기 작업의 동기적 표현 - Promise + Async/await> 부분을 다시 공부했다.

1. Promise란 비동기 처리에 대해, 처리가 끝나면 알려달라는 약속입니다.

2. new 연산자로 호출한 Promise 인자로 넘어가는 콜백은 바로 실행돼요.

3. 그 내부의 resolve(또는 reject) 함수는 호출하는 구문이 있을 경우 resolve(또는 reject) 둘 중 하나가 실행되기 전까지는 다음(then), 오류(catch)로 넘어가지 않습니다.

4. 따라서, 비동기작업이 완료될 때 비로소 resolve, reject를 호출합니다.

5. 그럼 await에 걸려있던 함수가 풀립니다.

 

동기처리로 되어 있는 기명함수로 되어 있는 식을 보겠습니다.

var coffeeList = '';

var addEspresso = function (name) {
	coffeeList = name;
	console.log(coffeeList);
	setTimeout(addAmericano, 500, '아메리카노');
};

var addAmericano = function (name) {
	coffeeList += ', ' + name;
	console.log(coffeeList);
	setTimeout(addMocha, 500, '카페모카');
};

var addMocha = function (name) {
	coffeeList += ', ' + name;
	console.log(coffeeList);
	setTimeout(addLatte, 500, '카페라떼');
};

var addLatte = function (name) {
	coffeeList += ', ' + name;
	console.log(coffeeList);
};

setTimeout(addEspresso, 500, '에스프레소');

함수안에서 그다음 함수를 호출하는 식으로 진행이 됩니다.

 

이제 이 부분을 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);
	});
});

여기서 new 연산자로 호출한 Promise 인자로 넘어가는 콜백은 바로 실행돼요.

따라서 에스프레소가 적혀있는 부분이 실행이 되고 resolve(name)은 prevName에 들어갑니다.

즉, prevName은 그 전 단계에 있던 name 변수에 할당된 value입니다.

 

일단, 이 부분에서 너무나도 메서드가 길기 때문에 보기 편하게 줄여보겠습니다.

var addCoffee = function (name) {
	return function (prevName) {
		return new Promise(function (resolve) {
			setTimeout(function () {
				var newName = prevName ? (prevName + ', ' + name) : name;
				console.log(newName);
				resolve(newName);
			}, 500);
		});
	};
};

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

addCoffee('에스프레소')()가 먼저 실행이 됩니다. 

왜냐하면 addCoffee(`에스프레소')라고만 하면

function (prevName) {
		return new Promise(function (resolve) {
			setTimeout(function () {
				var newName = prevName ? (prevName + ', ' + name) : name;
				console.log(newName);
				resolve(newName);
			}, 500);
		});

이 부분이 실행이 되는 겁니다.

이게 무슨 뜻이냐면

var addCoffee = function (name) { return ... } 이렇게 되어 있기 때문에

안에 있는 함수를 한번더 실행해야 그다음 return문에 있는 new Promise가 바로 실행이 되는 거죠.

 

이제 날 가장 힘들게 했던 Promise + 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();

coffeeMaker()가 실행되면 이제 async function() { } 부분이 실행 되기 시작합니다.

그리고  내려가다보면 await _addCoffee('에스프레소');가 호출이 되고 이거에 의해서 await addCoffee(name)이 호출이 됩니다.

이때 먼저 만들어 두었던 new Promise 함수가 실행이 되는 겁니다.

이때의 resolve(name)은 그냥 끝마쳤다 그다음 것으로 넘어가도 된다 라는 뜻으로 보면 될 것 같습니다.

 

솔직히 강의에 관한걸로 공부를 한다고 해서 이번 개인과제 주어진 문제를 아직은 비동기로 푸는 법에 대해서 잘 모르겠습니다.

이 부분을 어떻게 하면 될지 현재 가장 고민이 되는 상태인데 일단 오늘 TIL을 작성한 후 다른 곳에서 좀더 공부를 진행 해서 비동기로 작성하는 법에 대해서 숙지를 해야 할 것 같습니다.