[ES6] PROMISES

Cho Dragoo·2021년 9월 3일
0

ES6 문법

목록 보기
2/3
post-thumbnail

'노마드코더의 ES6의 정석' 동영상 강의를 토대로 복습한 내용입니다.

프로미스는 자바스크립트 비동기 처리에 사용되는 객체다.

API가 실행되면 서버에 요청을 보내는데 JS의 특정상 모든 데이터를 받기전에 실행되려고 하며 따라서 오류가 발생하거나 빈 화면이 뜨게된다.

이와 같은 문제점을 해결하기 위한 방법 중 하나가 프로미스라고 한다.



Creating Promises

프로미스의 3가지 상태(states)

  • Pending(대기) : 비동기 처리 로직이 아직 완료되지 않은 상태
  • Fulfilled(이행) : 비동기 처리가 완료되어 프로미스가 결과 값을 반환해준 상태
  • Rejected(실패) : 비동기 처리가 실패하거나 오류가 발생한 상태
function getData() {
  return new Promise(function(resolve, reject) {  
// new Promise()이 대기(Pending) 상태로 만듬 
// 콜백 함수의 인자는 resolve, reject
    var data = 100;
    resolve(data); // resolve()은 이행(Fulfilled) 상태로 만듬
  });
}

// resolve()의 결과 값 data를 resolvedData로 받음
getData().then(function(resolvedData) {
// 이행 상태가 되면 아래와 같이 then()을 이용해 결과값을 받는다.
  console.log(resolvedData); // 100
});

※ 프로미스의 '이행' 상태는 곧 완료를 뜻한다.



Chaining Promises

const arm = new Promise((resolve, reject) => {
resolve(2)
})

arm.then(num => {
console.log(num * 2);
return num * 2
}).then(other => {
console.log(other * 2)
})

// 4
// 8
  • then()은 이전 결괏값을 그대로 매개변수로 받아 실행해준다.

const arm = new Promise((potato, reject) => {
potato(2)
})

const chainning = num => num * 3

arm.then(chainning)
.then(chainning)
.then(chainning)
.then(endNum => console.log(endNum))

// 54
  • 로직내용을 변수로 할당해 then()의 내부에 넣는 방법도 있다.



Promise.all

모든 Promise 생성자들을 한꺼번에 실행하게 해주는 메서드

const p1 = new Promise((resolve) => {
setTimeout(resolve, 3000, "First");
});
const p2 = new Promise((resolve, reject) => {
setTimeout(resolve, 2000, "second");
});
const p3 = new Promise((resolve) => {
setTimeout(resolve, 1000, "third");
});

const motherPromise = Promise.all([p1, p2, p3]);

Promise.all([p1, p2, p3])
.then((value) => console.log(value))
.catch((err) => console.log(err));

//3초 뒤에 ["First", "second", "third"] 출력
  • 가장 느린 프로미스 객체의 실행이 끝나면 출력되는게 특징이다.



Promise.race

const p1 = new Promise((resolve) => {
setTimeout(resolve, 10000, "First");
});
const p2 = new Promise((resolve, reject) => {
setTimeout(reject, 1000, "second");
});
const p3 = new Promise((resolve) => {
setTimeout(resolve, 3000, "third");
});

const motherPromise = Promise.race([p1, p2, p3]);

motherPromise
.then((value) => console.log(value))
.catch((err) => console.log(err));

// second
  • 가장 빨리 끝내는 객체 하나가 콘솔창에 출력된다. 즉 결과적으로 1초후에 불려지는 "second"만 출력된다.
  • 이 코드의 특성을 활용한다면 데이터 로딩이 너무나 늦을 때 대신해주는 객체를 실행시키는 방법도 있을 것이다.



finally()

const p1 = new Promise((resolve, reject) => {
setTimeout(resolve, 1000, "First");
})
.then((value) => console.log(value))
.catch((e) => console.log(`${e}error`))
.finally(() => console.log("Im done"));

// First
// Im done
  • finally()resolve를 작동못해 에러가 있더라도 then()이 실행 못하더라도 바로 작동한다. 예문처럼 resolve가 정상실행하면 then()이 실행되어 First를 출력한다.
    반면에 정상실행을 못해주면 catch()가 실행된다.

  • finally()의 유용한 쓰임이 있다면 API를 호출할 때 로딩에 관련된 무언가를 할 때일 것이다.



응용

Promises문법을 응용한 내장메서드는 fetch()가 있다.
존재하는 웹사이트나 json파일에서 데이터를 파싱할때 유용하다.
이외에도 jquery-ajaxAxios라는 라이브러리는 좀 더 수월한 개발을 도와준다.

fetch("http://shibe.online/api/shibes?count=3/")
  .then((response) => {
    console.log(response);
    return response.json();
  })
  .then((json) => console.log(json))
  .catch((e) => console.log(`${e}`));

fetch("https://randomfox.ca/floof/")
  .then((response) => {
    console.log(response);
    return response.json();
  })
  .then((json) => console.log(json))
  .catch((e) => console.log(`${e}`));

// Promise {<pending>}[[Prototype]]: Promise[[PromiseState]]: "fulfilled"[[PromiseResult]]: undefined
    
// Response {type: "basic", url: "http://shibe.online/api/shibes?count=3/", redirected: false, status: 200, ok: true, …}
    
// ["https://cdn.shibe.online/shibes/bfe78e67f66305d3ac23d5d690d8c7cfea24c785.jpg"]
    
// Response {type: "cors", url: "https://randomfox.ca/floof/", redirected: false, status: 200, ok: true, …}
    
// {image: "https://randomfox.ca/images/13.jpg", link: "https://randomfox.ca/?i=13"}
  • api에서 데이터를 호출할 때 위 예제처럼 똑같은 로직인데도 불러오는데 성공하는것도 있고 실패하는 것도 있다.
    단순히 서버쪽에서 문제일수도 있지만 이런 경우는 불러올 데이터 형식이 어떻냐에 따라 결정되는게 아닌가 추측된다. 데이터를 보내줄 서버가 이상이 생겨서였던것 같다. 현재는 잘 불러와진다.

{
"image": "https://randomfox.ca/images/68.jpg",
"link": "https://randomfox.ca/?i=68"
}
  • randomfox의 데이터는 {}, 즉 객체 타입이고

[
"https://cdn.shibe.online/shibes/6ee5b89da2933f9e397bc934b174f23c9012974e.jpg"
]
  • shibe의 데이터는 [], 배열 타입이였다.
    배열 타입은 일반적인 응답처리로는 해결이 되지가 않는 것 같다.
    하지만 타입과 상관없이 응답해준다.
profile
어떤 문제든 파악 할 수 있으며 해결책을 찾을 수 있는 개발능력을 꿈꾸고 있습니다.

0개의 댓글