자바스크립트 코딩의 기술_외부 데이터에 접근하라

자바스크립트 2021. 6. 27. 19:13

(본 포스팅은 길벗의 '자바스크립트-코딩의 기술' 책을 공부하면서 작성되었습니다_내돈내산)

 

1. Promise를 이용해 비동기적으로 데이터를 가져오라.

  • 비동기 언어의 가치는 지연된 정보를 기다리는 동안 이 정보가 필요하지 않은 다른 코드를 실행할 수 있다는 점에 있다. API 응답을 기다리는 동안 여전히 다른 요소의 클릭 메서드에 응답하거나 다른 데이터 원본에 있는 값을 계산할 수 있다.
  • Promise가 등장하기 전에는 콜백함수를 사용해 비동기 작업을 처리했다. 데이터 원본에 뭔가를 요청할때 콜백함수를 인수로 넘겨준 다음 이 함수가 비동기 데이터를 가져온 후에는 콜백함수를 호출하고 실행한다.
  • 콜백함수는 비동기 데이터를 다루는 좋은 방법이고, 오랫동안 표준적인 방법이었다. 문제는 비동기함수에서 또 비동기 함수를 호출하고, 거기서 또 비동기 함수를 호출해 마침내 너무 많은 콜백함수가 중첩되는 경우가 생기는 것이다.
  • 이런 상황에서 Promise를 사용하면 콜백함수 문제를 해결할 수 있다. Promise는 콜백함수를 인수로 받는대신에 성공과 실패에 대응하는 메서드를 사용한다. 그리고 콜백함수를 중첩하는 대신에 여러개의 비동기 Promise를 연결할 수도 있다.
// Promise의 성공일경우
function getUserPreferences() {
  const preferences = new Promise((resolve, reject) => {
    resolve({
      theme: 'dusk',
    });
  });
  return preferences;
}

getUserPreferences()
  .then(preferences => {
    console.log(preferences.theme);
  });
  
----------------------------------------------------------------------------------------------
// Promise가 실패일 경우
function failUserPreference() {
  const finder = new Promise((resolve, reject) => {
    reject({
      type: 'Access Denied',
    });
  });
  return finder;
}

failUserPreference()
  .then(preferences => {
  // This won't execute
    console.log(preferences.theme);
  })
  .catch(error => {
    console.error(`Fail: ${error.type}`);
  });
  • Promise는 비동기 작업을 전달받아서 응답에 따라 두 가지 메서드 중 하나를 호출하는 객체이다.
    - Promise는 비동기 작업이 성공하거나 충족된 경우 then( ) 메서드에 결과를 넘겨준다.
    - 비동기 작업에 실패하거나 거부되는 경우에는 Promise가 catch( ) 메서드를 호출한다.
    - then( )과 catch( ) 메서드에는 모두 함수를 인수로 전달한다.
    - 이때 두 메서드에 인수로 전달되는 함수에는 비동기 작업의 결과인 응답만 인수로 전달된다.
    - Promise는 두개의 인수, 코드가 의도대로 동작했을 때 resolve( )와 실패했을 때 reject( ) 를 전달받는다.
    - resolve( )가 호출되면  then( ) 메서드에 전달된 함수가 실행된다. reject( ) 가 호출되면 then( )은 건너뛰고 catch() 메서드가 처리된다. 
    - Promise를 연결하는 경우엔 catch( ) 메서드를 개별적으로 연결할 필요가 없다. catch( ) 메서드를 하나만 정의해서 프라미스가 거절되는 모든 경우를 처리할 수 있다.

2. async/await 로 함수를 명료하게 생성하라.

  • async 키워드를 이용해서 선언한 함수는 비동기 데이터를 사용한다는 것을 의미한다.
  • 비동기 함수의 내부에서 await 키워드를 사용하면 값이 반환될 때까지 함수의 실행을 중지시킬 수 있다.
  • async/await는 Promise 문법을 대체하지는 않는다.
// Promise를 사용한 비동기 처리
getUserPreferences()
  .then(preferences => {
    console.log(preferences.theme);
});

// async/await를 사용한 비동기 처리
async function getTheme() {
  const { theme } = await getUserPreferences();
  return theme;
}
  • function 키워드 앞에 async 키워드를 추가해 비동기 함수를 호출한다는 것을 표시한다.
  • 함수를 호출하기 전에 await 키워드를 추가해서 함수가 Promise 객체를 반환한다는 것을 알려줘야 한다. 이런식으로 하면 Promise가 완료되었을 때 반환되는 값이 새로운 변수에 담긴다.
  • 비동기함수는 Promise로 변환되고 위의 getTheme( )를 호출해도 여전히 then( ) 메서드가 필요하다.
async function getArtistByPreference() {
  const { theme } = await getUserPreferences();
  const { album } = await failMusic(theme);
  const { artist } = await getArtist(album);
  return artist;
}

getArtistByPreference()
  .then(artist => {
    console.log(artist);
  })
  .catch(e => {
    console.error(e);
  });
  • async함수의 용도가 중요할 때는 여러개의 Promise를 다룰때이다. 
  • Promise와 동일하게 then( )과 catch( )를 이용해 비동기 함수로부터 데이터를 받고, 오류처리를 할 수 있다.

3. fetch로 간단한 Ajax 호출을 처리하라.

  • fetch( )는 Ajax 호출을 처리할수 있는 간단한 도구이다.
  • 대부분의 최신브라우저에서 지원되지만 Node.js 에서는 기본적으로 지원이 되지 않아 node-fetch 패키지를 사용해야 한다.
  • fetch( )호출은 end-point URL을 인수로 하여 실행하면 된다.
// fetch() 메서드의 기본 형태
fetch('https://jsonplaceholder.typicode.com/posts/1');
/*
{
  userId: 1,
  id: 1,
  title: 'First Post',
  body: 'This is my first post...',
};
*/
const update = {
  title: 'Clarence White Techniques',
  body: 'Amazing',
  userId: 1,
};
// fetch메서드에 세부옵션을 넣어 데이터를 받아올 수 있다.
const options = {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify(update),
};

fetch('https://jsonplaceholder.typicode.com/posts', options).then(data => {
  // data필드의 ok속성은 Edge에서만 지원한다
  // 상태코드가 반환되면 그 작업은 오류가 난것이 아니기 때문에 반드시 관련 분기처리를 해주어야 함.
  // catch() 메서드만으로는 오류처리를 전부 할 수 없음.
  if (!data.ok) {
    throw Error(data.status);
  }
  return data.json();
}).then(update => {
  console.log(update);
  // {
  //   title: 'Clarence White Techniques',
  //   body: 'Amazing',
  //   userId: 1,
  //   id: 101
  // };
}).catch(e => {
  console.log(e);
});

4. localStorage로 상태를 장기간 유지하라

  • localStorage는 브라우저에만 존재하는 작은 데이터베이스와 같다. localStorage에 정보를 추가하거나 가져올 수 있지만, 브라우저의 자바스크립트에서 직접적으로 접근할 수 없다.
// localStorage 객체에 원하는 값을 저장하는 경우 => setItem()
function saveBreed(breed) {
  localStorage.setItem('breed', breed);
}
// localStorage 객체에서 원하는 값을 가져오는 경우 => getItem()
function getSavedBreed() {
  return localStorage.getItem('breed');
}
// localStorage 객체에서 추가했던 항목을 삭제하는 경우 => removeItem()
function removeBreed() {
  return localStorage.removeItem('breed');
}
  • 다른 객체와 마찬가지로 원하는 만큼 키를 추가할 수 있으며, 사용자가 설정한 모든 조건을 저장하고 싶은 경우에는 항목별, 그룹별로 저장이 가능하다.
// JSON 을 문자열로 바꾸어 저장하는 방법
function savePreferences(filters) {
  const filterString = JSON.stringify([...filters]);
  localStorage.setItem('preferences', filterString);
}
// 가져온 데이터(문자열)을 JSON 형태로 변환해서 사용하는 방법
function retrievePreferences() {
  const preferences = JSON.parse(localStorage.getItem('preferences'));
  return new Map(preferences);
}
// localStorage의 모든 데이터를(키-값 쌍) 초기화하기위한 clear() 메서드 
function clearPreferences() {
  localStorage.clear();
}
  • localStorage의 유일한 단점은 데이터가 반드시 문자열이어야 한다는 것이다. localStorage에는 배열이나 객체는 저장할 수 없지만 다행이 JSON.stringify( )와 같은 문자열변환을 통해 저장할 수 있다. 가져온 문자열데이터를 다시 원하는 형태로 parsing 해서 사용하면 된다.
admin