[JS] 콜백, promise, async/await의 차이

YJS·2022년 7월 5일
0

Node JS 프로젝트

목록 보기
3/4

자바스크립트의 비동기 처리 특징

☝️비동기 처리란?
특정 코드의 연산이 끝날때까지 코드의 실행을 멈추지 않고 다음 코드를 먼저 실행하는 특성

예시1) ajax

function getData() {
	var tableData;
	$.get('https://domain.com/products/1', function(response) {
		tableData = response;
	});
	return tableData;
}

console.log(getData()); // undefined

-> get 요청의 결과를 기다리지 않고 return tableData를 실행했으므로 결과 값은 초기 값을 설정하지 않은 undefined

🤓비동기처리 = 특정 로직의 실행이 끝날때까지 기다리지 않고 나머지 코드를 먼저 실행하는 것

비동기 처리의 문제 해결 방법

1. 콜백 함수

function getData(callbackFunc) {
	$.get('https://domain.com/products/1', function(response) {
		callbackFunc(response); // 서버에서 받은 데이터 response를 callbackFunc() 함수에 넘겨줌
	});
}

getData(function(tableData) {
	console.log(tableData); // $.get()의 response 값이 tableData에 전달됨
});

❗그러나,
콜백 비동기 처리 로직을 위해 콜백 함수를 연속해서 사용할 경우 콜백 지옥에 빠질 수 있다. 이를 해결 하는 방법이 promise 혹은 async 이다.

2. Promise

💡프로미스란?
자바스크립트 비동기 처리에 사용되는 객체로 주로 서버에서 받아온 데이터를 화면에 출력할 때 사용

콜백으로 처리한 1의 코드를 promise로 수정

function getData(callback) {
  // new Promise() 추가
  return new Promise(function(resolve, reject) {
    $.get('url 주소/products/1', function(response) {
      // 데이터를 받으면 resolve() 호출
      resolve(response);
    });
  });
}

// getData()의 실행이 끝나면 호출되는 then()
getData().then(function(tableData) {
  // resolve()의 결과 값이 여기로 전달됨
  console.log(tableData); // $.get()의 reponse 값이 tableData에 전달됨
});

-> new Promise() 메서드를 호출하면 pending 상태
-> new Promise() 메서드 호출 시 콜백 함수 선언 가능. 콜백 함수 인자는 resolve, reject
-> resolve를 실행하게 되면 fulfilled 상태로 변함
-> 이행(fulfilled) 상태가 되면 then() 사용하여 처리 결과 값을 받을 수 있음

function getData() {
  return new Promise(function(resolve, reject) {
    reject(new Error("Request is failed"));
  });
}

// reject()의 결과 값 Error를 err에 받음
getData().then().catch(function(err) {
  console.log(err); // Error: Request is failed
});

-> 실패 상태가 되면 처리 결과값을 catch로 받을 수 있음

💁‍♂️프로미스의 3가지 처리과정
(new Promise()로 프로미스를 생성하고 종료될 떄까지 갖는 상태 3가지)
•pending: 대기. 비동기 처리 로직이 아직 완료되지 않은 상태
•fulfilled: 이행. 비동기 처리 완료. 프로미스가 결과 값 반환해준 상태
•rejected: 실패. 비동기 처리 실패 혹은 오류 발생 상태

☝️여러개의 프로미스를 연결하여 사용 가능.

new Promise(function(resolve, reject){
  setTimeout(function() {
    resolve(1);
  }, 2000);
})
.then(function(result) {
  console.log(result); // 1
  return result + 10;
})
.then(function(result) {
  console.log(result); // 11
  return result + 20;
})
.then(function(result) {
  console.log(result); // 31
});

☝️프로미스의 에러처리 방법

function getData() {
  return new Promise(function(resolve, reject) {
    reject('failed');
  });
}

// 1. then()의 두 번째 인자로 에러를 처리하는 코드
getData().then(function() {
  // ...
}, function(err) {
  console.log(err);
});

// 2. catch()로 에러를 처리하는 코드
getData().then().catch(function(err) {
  console.log(err);
});

-> 주로 2번째 방법인 catch 를 사용함.

3. async/await

💡async/await이란?
자바스크립트의 비동기 처리 문법 중 가장 최근 버전. 콜백과 프로미스의 단점을 보완.

콜백 사용시)

function logName() {
  var user = fetchUser('domain.com/users/1', function(user) {
    if (user.id === 1) {
      console.log(user.name);
    }
  });
}

async/await 사용시)

async function logName() {
  var user = await fetchUser('domain.com/users/1');
  if (user.id === 1) {
    console.log(user.name);
  }
}

-> async/await을 사용하면 복잡한 코드가 간결해지고 위에서부터 아래로 순차적으로 읽으면서 사고하는 것이 가능함.

☝️async/await 문법

async function 함수명(){
await 비동기처리메서드명();
}

function fetchUser() {
  var url = 'https://jsonplaceholder.typicode.com/users/1'
  return fetch(url).then(function(response) {
    return response.json();
  });
}

function fetchTodo() {
  var url = 'https://jsonplaceholder.typicode.com/todos/1';
  return fetch(url).then(function(response) {
    return response.json();
  });
}
async function logTodoTitle() {
  try {
    var user = await fetchUser();
    if (user.id === 1) {
      var todo = await fetchTodo();
      console.log(todo.title); // delectus aut autem
    }
  } catch (error) {
    console.log(error);
  }
}

-> fetchUser 이용하여 사용자 정보 추출.
-> 받아온 사용자 정보인 user.id를 1과 비교
-> fetchTodo 이용하여 todo.title 콘솔에 출력

출처:
1. https://joshua1988.github.io/web-development/javascript/javascript-asynchronous-operation/
2. https://joshua1988.github.io/web-development/javascript/promise-for-beginners/
3. https://joshua1988.github.io/web-development/javascript/js-async-await/

profile
우당탕탕 개발 일기

0개의 댓글