promise, Axios, async, await 간단사용

김범식·2023년 4월 21일
0
post-thumbnail

javascript의 세계에서는 거의 대부분의 작업들이 비동기로 이루어진다. 이전에는 버튼을 눌렀을 때(이벤트 발생) 특정 작업을 수행하는 정도의 수준이었기 때문에 복잡도가 높지 않았지만 최근에는 프론트엔드의 규모가 상당히 커져서 javascript로 작성하는 코드를 단순한 수준을 넘어섰다.
이렇게 복잡도 가 높아지는 상황, 특히 어려워지는 케이스는 콜백이 중첩되는 경우다.

이러한 콜백지옥을 벗어나기 위해 현재의 Promise패턴이 ES6 문법에 정식으로 포함되었다.

대표적으로 콜백 지옥을 탈출하여 프로미스를 사용해 단순해지는 코드를 보자



콜백지옥

const fs = require('fs');

fs.readFile('file.txt', 'utf8', (err, data) => {
  if (err) {
    console.error(err);
  } else {
    console.log(data);
    fs.readFile('file2.txt', 'utf8', (err2, data2) => {
      if (err2) {
        console.error(err2);
      } else {
        console.log(data2);
        fs.readFile('file3.txt', 'utf8', (err3, data3) => {
          if (err3) {
            console.error(err3);
          } else {
            console.log(data3);
          }
        });
      }
    });
  }
});





then catch 사용

const fs = require('fs/promises');

fs.readFile('file.txt', 'utf8')
  .then((data) => {
    console.log(data);
    return fs.readFile('file2.txt', 'utf8');
  })
  .then((data2) => {
    console.log(data2);
    return fs.readFile('file3.txt', 'utf8');
  })
  .then((data3) => {
    console.log(data3);
  })
  .catch((err) => {
    console.error(err);
  });

훨씬 가독성 좋고 깔끔한 코드가 완성되었다.



Promise()


//Promise 선언
var _promise = function (param) {

	return new Promise(function (resolve, reject) {

		// 비동기를 표현하기 위해 setTimeout 함수를 사용 
		window.setTimeout(function () {

			// 파라메터가 참이면, 
			if (param) {

				// 해결됨 
				resolve("해결 완료");
			}

			// 파라메터가 거짓이면, 
			else {

				// 실패 
				reject(Error("실패!!"));
			}
		}, 3000);
	});
};

//Promise 실행
_promise(true)
.then(function (text) {
	// 성공시
	console.log(text);
}, function (error) {
	// 실패시 
	console.error(error);
});

이 코드에 promise에 대한 모든 개념이 담겨있다. 비동기로 로직이 실행되며 성공시 resolve안에 있는 값을 반환하고 실패시 reject안에 있는 값을 반환한다. 그리고 그 값들을 then과 catch로 처리하고 있다.



개념


promise : 객체는 비동기 작업에 대한 응답의 완료 또는 실패와 그 결과 값을 나타낸다.



기본 예제

function asyncTask() {
  return new Promise(function(resolve, reject) {
    setTimeout(function() {
      resolve('Task completed successfully!');
    }, 2000);
  });
}

asyncTask()
  .then(function(result) {
    console.log(result);
  })
  .catch(function(error) {
    console.log(error);
  });

promise함수가 성공적으로 동작하여 2초 후에 then에서 task completed successfully 가 출력되게 된다.

function asyncTask() {
return new Promise(function(resolve, reject) {
setTimeout(function() {
reject(new Error('Task failed!'));
}, 2000);
});
}
asyncTask()
.then(function(result) {
console.log(result);
})
.catch(function(error) {
console.log(error);
});

reject가 동작했을 경우의 promise함수이다.

reject함수를 호출했고 실행했을 때 catch가 받아 console.log에 error를 출력한다.



변수에 담아서 사용하는 promise

const myPromise = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve('Hello World!');
  }, 1000);
});

myPromise.then(result => {
  console.log(result); // 'Hello World!' 출력
}).catch(error => {
  console.error(error); // 오류 발생 시 처리
});

아까는 함수로 리턴했지만 변수에 담아서 사용할 수도 있다.



실전에서 사용하는 promise


일반적으로 비동기 작업이란 네트워크 요청, 파일 읽기/쓰기, 타이머 등과 같이 시간이 걸리는 작업을 말한다. Promise는 이러한 비동기 작업을 처리할 때 결과값을 반환하거나 오류를 처리하는데 유용하다.

promise의 사용방법의 기초적인 예시이다 여기서는 타이머를 사용해서 promise를 구현했다.



Axios에서 promise사용


axios.get('https://jsonplaceholder.typicode.com/posts/1')
  .then(response => {
    console.log(response.data);
  })
  .catch(error => {
    console.log(error);
  });

javascript에서 http요청을 보낼 때 axios라는 비동기 함수를 사용한다. axios는 내부적으로 promise객체를 반환하기 대문에 다음과 같이 .then과 catch를 사용할 수 있다.

async, await와 Axios사용

async function fetchPost() {
  try {
    const response = await axios.get('https://jsonplaceholder.typicode.com/posts/1');
    console.log(response.data);
  } catch (error) {
    console.log(error);
  }
}

fetchPost().then(() => {
  console.log('HTTP 요청이 완료되었습니다.');
}).catch(() => {
  console.log('HTTP 요청이 실패하였습니다.');
});

async함수도 promise객체를 반환하기 때문에 then과 catch를 사용할 수 있다. 따라서 비동기 작업이 가능한다. 근데 사실 try catch문 없이도 작업해도 then과 catch가 알아서 실패,성공 여부를 판별해서 작업해준다.



async 함수에서 에러 발생시키기

async function myAsyncFunction() {
  return Promise.reject(new Error('Something went wrong'));
}

myAsyncFunction().then(result => {
  console.log(result);
}).catch(error => {
  console.log(error.message); // Something went wrong
});

promise.reject를 반환하면 의도적으로 .catch에 걸리게 만들 수 있다.



async 함수에서 올바른 결과 리턴하기

async function myAsyncFunction() {
  return Promise.resolve('Hello World');
}

myAsyncFunction().then(result => {
  console.log(result); // Hello World
}).catch(error => {
  console.log(error);
});

의도적으로 올바른 값을 리턴하는 async 함수를 만들었다.

사실 이렇게 의도적으로 에러와 올바른 값을 반환할 필요는 없다.

실제로는 알아서 에러와 올바른 값을 구분해 주기 때문이다.




다음 코드를 살펴보자

async function fetchData() {
  const response = await axios.get('https://example.com/api/posts');
  console.log(response.data);
}

fetchData()
	.then(res => console.log(res))
  .catch(error => console.error(error));

-의도적으로 값을 반환하지 않더라도 올바른 값이 넘어오면 then을 실행하고 error가 발생하면 catch문에 자동으로 잡히게 된다!



then catch를 잘 사용하고 있었지만 그의 기초가 되는 promise는 정작 제대로 공부하지 않아서 정리해 두었다. promise객체를 반호나한다는 것의 의미를 알것같다.

profile
frontend developer

0개의 댓글