AJAX _ new Promise

Eunsu·2021년 11월 2일
0

@ Ajax / HTTP

목록 보기
3/3
post-thumbnail

전 포스팅에서 비동기와 콜백에 대해서 살펴봤는데, 순차적으로 데이터를 받아오고, 뭔가 처리하는 과정에서 콜백 함수가 남발되고 가독성이 떨어지고, 애러가 발생하거나 디버깅을 할 때 처리하기가 힘들어진다.

이러한 문제를 해결하기 위해 여러 라이브러리들이 등장했고, 그 중에서 개발자들에게 널리 선택받은 것이 바로 Promise 패턴을 사용한 라이브러리들(jQuery Deffered, Q, Bluebird)이다. 이 라이브러리들이 표준화되어, 결국 ES2015에 이르러 JavaScript 언어 자체에 포함되게 되었다.

🟦 Promise

💛 Promise란?

🔸 promise는 자바스크립트 비동기 처리에 사용되는 객체이다. Promise 객체가 만들어 지는 시점에는 그 안에 무엇이 들어갈 지 모를 수도 있다. 대신 then 메서드를 통해 콜백을 등록해서 작업이 끝났을 때 결과앖을 가지고 추가 작업을 할 수 있다.

❗ Promise 가 필요한 이유

const $= require('jquery');
console.log(1)
function getData(callback){
  console.log(3) $.get('https://jsonplaceholder.typicode.com/users',function(res){
    console.log(4)  
  callback(res)
  })
}
getData(function(data){
  console.log(2)
  console.log(data)
})

이렇게 AJAX로 데이터를 받아올 경우,

200명의 user의 정보가 들어있는 API를 가공해, 새로운 값을 넣고 body에 나타나게 하려면 콜백함수도 많이 사용되고 코드실행도 많이됨.

getData('https://jsonplaceholder.typicode.com/todos',function(data){
  const arr= data.filter(user => user.userId === 10)
  arr.map(user => {
    if(user.completed){
      const newUser= {...user,pass:true}
      const elem= $(`<p>${newUser.id} ${newUser.title}</p>`)
      return document.body.append(elem[0])
    } 
  })
})

💜 Promise 예제

❗ Promise 플로우

  • Pending(대기) => new Promise() 호출
  • Fulfilled(이행) =>function(resolve,reject){resolve()}
  • Rejected(실패) => function(resolve,reject){reject()}

❗ Promise 예제

const $= require('jquery');
function getData(){
  return new Promise(function(resolve,reject){
   //pending
    $.get('https://jsonplaceholder.typicode.com/todos',function(res){
      if(res) resolve(res);
      //Fulfilled
      reject(new Error('Faild!'))
      //rejected
    })
  })
}
// $.get()의 호출결과에따라 data / error 출력
getData().then(function(data){
  console.log(data)
}).catch(function(err){
  console.log(err)
})

❗ 여러개의 promise 연결

콜백 Version

function print(ms) {
  return console.log(`print${ms}`);
}
function timer(ms, callback) {
  setTimeout(callback, ms);
}
timer(1000, () => {
  print(1000);
  timer(2000, () => {
    print(2000);
    timer(3000, () => {
      print(3000);
      timer(4000, () => {
        console.log("finish");
      });
    });
  });
});
// print1000 -> print2000 -> print3000 -> finish

Promise Version

function print(ms) {
  return console.log(`print${ms}`);
}
function timer(callback) {
  return new Promise(function (resolve, reject) {
    setTimeout(() => {
      callback;
      resolve();
    }, 1000);
  });
}
timer(print(1000))
  .then(() => timer(print(2000)))
  .then(() => timer(print(3000)))
  .then(() => {
    console.log("finish");
  });

.then() 메서드를 사용하면 ms를 다시 지정할 필요 없이, timer()가 호출된 뒤 순차적으로 then()을 타고 가므로 콜백함수만 넣어주면 된다. 짱편함.

💔 Promise 애러처리

❗ catch() 사용하기

getData().then(function(result) {
  console.log(result); // hi
  throw new Error("Error in then()");
}).catch(function(err) {
  console.log('then error : ', err); // then error :  Error: Error in then()
});

❗ 예제를 통한 애러 핸들링

const sunny = () => 
  new Promise((resolve, reject) => {
    setTimeout(() => resolve(`🌤`), 1000);
  });
const cloud = (sun) => 
  new Promise((resolve, reject) => {
    setTimeout(() => resolve(`${sun} => 🌦`), 1000);
  });;
const rain = (sun) => 
  new Promise((resolve, reject) => {
    setTimeout(() => resolve(`${sun} => 🌧`), 1000);
  });
;
sunny()
  .then(sun => cloud(sun))
  .then(sun => rain(sun))
  .then(result => console.log(result)).catch(err =>console.log(err))
  // 🌤 => 🌦 => 🌧 

🔸 애러가 발생한다면 들어갈 코드 중간에 끼어넣으면 error 메세지가 끼지 않고 대체됨.

const cloud = (sun) => 
  new Promise((resolve, reject) => {
    setTimeout(() => reject(new Error(`${sun} => 🌦`)), 1000);
  });;
  sunny()
  .then(sun => cloud(sun))
  .catch(err =>`🌩`)
  .then(sun => rain(sun))
  .then(result => console.log(result))
  //🌩 => 🌧 

💞 Ellie's Promise

❗ 공부관점

  • state : resolve / reject
  • Producer(new Promise) vs Consumer(then,catch,finally)

❗ Promise는 선언되는 순간 즉시 실행됨.

그래서 클릭해야만 통신해야 되는 경우 주의해야 함.

const promise1 =() => {
   new Promise((resolve,reject) => {
    console.log('click Promise')
  })
}
document.getElementById('btn').addEventListener('click',promise1)

❗ then() , catch() , finally()

  • then(정상적으로 처리되었을 때 실행될 메서드, 인자 : 결과값)
  • catch(애러가 났을 때 실행될 메서드, 인자:error)
  • finally (결과값에 상관없이 실행되는 메서드, 인자 : 없음)
const promise = new Promise((resolve, reject) => {
  setTimeout(() => {
    // resolve("eunsu");
    reject(new Error('find error'))
  }, 2000);
});
promise
  .then((result) => console.log("then"))
  .catch((err) => console.log(err))
  .finally(() => console.log("finally"));

◾ error는 자바스크립트에서 제공하는 오브젝트인 new Error를 사용해서 애러를 잡음.

profile
function = (Develope) => 'Hello World'

0개의 댓글

관련 채용 정보