Today I Learned

promise와 then / async와 await

리꾸엘메 2022. 4. 3. 14:44

자바스크립트의 함수 실행

- 위에서 아래로 읽어내려오면서 코드를 실행한다. 

- 선언된 함수가 아닌 호출된 함수를 실행한다. 

- 싱글스레드 언어로 작업을 순차적으로 하나씩 실행한다.

- 하지만 웹API에 비동기작업을 위임하고 동시에 다음 작업을 진행할 수 있다. 

 

비동기작업의 처리 과정: 

① 콜스택(실행할 함수가 쌓이는 곳)에 콜이 쌓인다. 

② 비동기작업은 웹API로 위임한다.

(웹API는? : Ajax, setTimeout(), Dom등 브라우저에서 제공하는 API)

③ 웹API에서 작업이 완료되면 콜백큐에 결과(콜백함수)를 전달

④ 콜백큐에서는 콜스택으로 다시 함수를 보내고, 콜스택에서 함수가 처리된다. 

 

비동기 작업이 중첩되는 경우 관리가 힘들어지고 이를 콜백헬이라고 부른다. 

promise는 비동기작업의 상태를 알기 위한 객체이다.

.then은 promise 이후의 동작을 수행하는 메서드이다.

promise와 then을 사용해 콜백헬 문제를 극복할 수 있다. 

 

let promise = new Promise((resolve, reject) => {
setTimeout(() => resolve("완료!"), 1000);
});

promise.then(result => {
console.log(result); 
}, error => {
console.log(error); });

// 결과값
// Promise {<pending>}
// 완료!

 프라미스에서 현재 상황을 알려주는 상태값은 네가지로 구분된다. 

- pending: 비동기 처리 수행 전(resolve, reject가 아직 호출되지 않음)
- fulfilled: 수행 성공(resolve가 호출된 상태)
- rejected: 수행 실패(reject가 호출된 상태)
- settled: 성공 or 실패(resolve나 reject가 호출된 상태)

 


new Promise(function(resolve, reject) {

  setTimeout(() => resolve(1), 1000); // (*)

}).then(function(result) { // (**)

  alert(result); // 1
  return result * 2;

}).then(function(result) { // (***)

  alert(result); // 2
  return result * 2;

}).then(function(result) {

  alert(result); // 4
  return result * 2;

});

then은 promise chaining 에서 유용하게 사용된다. 

주의할 점은 연산이 순차적으로 연결되는 경우에 chain이라는 점을 기억해야 한다. 

 


async function myFunc(){
	let promise = new Promise((resolve, reject) => {
		setTimeout(() => resolve("완료!"), 1000);
	});

    console.log(promise); // 결과값은 <pending>

	let result = await promise; // pormise가 끝날 때 까지 기다린다. 

    	console.log(promise);

		console.log(result); // <fulfilled>와 '완료!' 가 출력된다.

async는 함수 앞에 붙여 항상 프라미스를 반환한다.

await는 async와 한 쌍으로 사용해, async함수가 프라미스를 반환할 때 까지 기다린 후 다음 작업을 수행한다. 

async와 await를 사용하면 가독성이 좋다.