본문 바로가기
Dev/Vue.js

[Vue.js] Hacker News - API 구현

by dev_jsk 2020. 9. 17.
728x90
반응형

axios를 이용한 API 호출

설치

npm i axios --save 실행

// Terminal
jskim@DESKTOP-SI6DJ17 MINGW64 /d/dev/study/vue-advanced/vue-news (master)
$ npm i axios --save

구현

1. src/api/index.js 생성

import axios from 'axios';

// 1. HTTP Request & Response와 관련된 기본 설정
const config = {
  baseUrl: "https://api.hnpwa.com/v0/",
};

// 2. API 함수들을 정리
function fetchNewsList() {
    // ES6 문법
    // 문자열 중간에 변수 대입하기
    // `${변수명}나머지 문자열`
    // 기존 변수명 + 문자열 과 동일
    return axios.get(`${config.baseUrl}news/1.json`);
}
function fetchAskList() {
    return axios.get(`${config.baseUrl}ask/1.json`);
}
function fetchJobsList() {
    return axios.get(`${config.baseUrl}jobs/1.json`);
}

// 3. 다른 곳에서 사용하기 위해 export
export {
    fetchNewsList
    , fetchAskList
    , fetchJobsList
}

2. NewsView.vue, AskView.vue, JobsView.vueindex.js import 및 API 함수 사용

<!-- NewsView.vue -->
<template>
  <div>
    <div v-for="user in users">{{ user.title }}</div>
  </div>
</template>

<script>
import { fetchNewsList } from "../api/index.js";

export default {
  data() {
    return {
      users: [],
    };
  },
  created() {
    var vm = this;
    fetchNewsList()
      .then(function (response) {
        vm.users = response.data;
      })
      .catch(function (error) {
        console.log(error);
      });
  },
};
</script>

<!-- AskView.vue -->
<template>
  <div>
    <div v-for="item in ask">{{ item.title }}</div>
  </div>
</template>

<script>
import { fetchAskList } from "../api/index.js";

export default {
  data() {
    return {
      ask: [],
    };
  },
  created() {
    var vm = this;
    fetchAskList()
      .then(function (response) {
        vm.ask = response.data;
      })
      .catch(function (error) {
        console.log(error);
      });
  },
};
</script>

<!-- JobsView.vue -->
<template>
  <div>
    <div v-for="job in jobs">{{ job.title }}</div>
  </div>
</template>

<script>
import { fetchJobsList } from "../api/index.js";

export default {
  data() {
    return {
      jobs: [],
    };
  },
  created() {
    fetchJobsList()
      .then(response => this.jobs = response.data)
      .catch(error => console.log(error));
  },
};
</script>

this

함수의 실행 컨텍스트(함수가 실행될 때의 컨텍스트)를 가리키는 예약어

상황에 따른 this

다른 언어와는 다르게 자바스크립트의 this는 상황에 따라 가리키는 값이 다르다.

 

첫번째 상황 this

console.log(this);  // window 객체를 가리킨다.

가장 기본적인 컨텍스트로 글로벌(전역) 컨텍스트이다. 여기서 window는 자바스크립트의 최상위 객체를 말한다.

 

두번째 상황 this

var obj = {
  num: 10,
  printNum: function() {
    console.log(this.num);
  }
};

obj.printNum();  // 10이 출력된다.

객체 속성 함수 안에서의 this는 기본적으로 해당 객체를 가리킨다.

 

세번째 상황 this

function showComment() {
  console.log(this);
}

showComment();  // window 객체를 가리킨다.

함수 선언문의 경우 실행시키면 window 객체를 가리키는 것을 알 수 있다. 따라서 일반 함수의 this는 전역 컨텍스트임을 알 수 있다.

function Developer() {
  console.log(this);
}

var dev = new Developer();  // Developer {} 가 출력된다.

생성자 함수의 경우 실행시키면 Developer {} 가 출력된다. 왜냐하면 new로 인스턴스를 생성하는 순간 함수가 실행되기 때문에 결론적으로 생성자 함수의 this는 함수의 내부를 가리킨다.

 

※ 자바스크립트는 프로토타입 기반 언어이기 때문에 클래스 없이 함수를 이용하여 인스턴스를 생성할 수 있다.

 

네번째 상황 this

function fetchData() {
  axios.get('domain.com/products')
       .then(function() {
         console.log(this);
       });
}

fetchData(); // window 객체를 가리킨다.

웹 개발 시 많이 마주하는 this 상황으로 데이터를 받아올 때 사용하는 HTTP 요청과 같은 비동기 처리 코드이다.

비동기 처리 코드의 콜백 함수를 실행시키면 window 객체를 가리키는 것을 알 수 있다. 따라서 비동기 처리 코드의 콜백 함수는 전역 컨텍스트를 가리키는 것을 알 수 있다.

자바스크립트 비동기 처리

Callback

함수 안에서 어떤 특정한 시점에 호출되는 함수. 보통 콜백 함수는 함수의 매개변수로 전달하여 특정 시점에서 콜백 함수를 호출하도록 한다.

 

예제

1. 익명 함수를 콜백 함수로 사용

// sum 함수 정의
function sum(a, b, callback) {
  var sum = a + b;
  callback(sum);
}

// sum 함수 호출 시 익명 함수를 콜백 함수로 사용
sum(1, 2, function(rst) {
  console.log(rst);
});

// 결과
3

2. 정의된 함수를 콜백 함수로 사용

// sum 함수 정의
function sum(a, b, callback) {
  var sum = a + b;
  callback(sum);
}

// 콜백 함수 정의
function print(rst) {
  console.log(rst);
}

// sum 함수 호출
sum(1, 2, print);

// 결과
3

콜백 함수 사용 이유

예제 코드를 보았을 때 콜백 함수를 사용하지 않고 순차적으로 호출하여 사용해도 같은 결과를 나타내기 때문에 굳이 콜백 함수의 필요성을 느끼기 어렵다.

그렇다면 예제를 순차적 처리로 구현하여 sum 함수의 리턴값을 print 함수의 매개변수로 전달한다고 할 때 sum 함수가 복잡한 로직으로 되어있어 시간이 오래 걸릴 경우 print 함수sum 함수의 동작이 끝나야 동작을 하기 때문에 print 함수의 동작이 지연되면서 다른 자바스크립트의 동작들을 할 수 없게 된다.

따라서 비동기 처리의 콜백 함수를 사용하여 동작이 끝날때 까지 기다리는 것이 아니라 종료되는 시점에 호출을 함으로써 효율성이 높고 여러 다른 동작을 할 수 있게 한다.

 

콜백 함수 사용의 문제점

  • 콜백 지옥(Callback Hell)
  • Code Indenting(코드 정렬)
  • 절차적 사고의 위배

Promise

비동기 작업이 맞이할 미래의 완료 또는 실패와 그 결과 값

 

상태

  • 대기(pending) : 이행하거나 거부되지 않은 초기 상태
  • 이행(fulfilled) : 연산이 성공적으로 완료됨
  • 거부(rejected) : 연산이 실패함

예제

function callAjax() {
  // Promise 객체 리턴
  return new Promise(function(resolve, reject) {
    $.ajax({
      url: 'https://api.hnpwa.com/v0/news/1.json',
      success: function(data) {
        // resolve() : 주어진 값으로 이행하는 Promise 객체 반환
        // reject() : 주어진 이유로 거부하는 Promise 객체 반환
        resolve(data);
      }
    });
  });
}

function fetchData() {
  var result = [];
  
  callAjax()
    // then() : Promise가 성공적으로 이뤄진 후 다음 작업 진행
    .then(function(data) {
      console.log('데이터 호출 결과', data);
      result = data;
    })
    // catch() : 에러 및 예외상황 발생으로 이뤄진 작업 진행
    .catch(function(error) {
      console.log(error);
    });  // 추가적인 체이닝 가능 (.then().catch()....)
}

참고

developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Promise

 

Promise

Promise 객체는 비동기 작업이 맞이할 미래의 완료 또는 실패와 그 결과 값을 나타냅니다.

developer.mozilla.org

 

728x90
반응형

댓글