foryouth 개발과정

DaewoongJeon·2021년 7월 28일
0

Web

목록 보기
6/6

2021. 7.27.~28.

2021. 7.29.

  • api 서버에서 데이터를 받아와 테이블 형태로 출력할 계획을 수립
    : 게시글 번호, 게시 날짜, 유형, 제목, 공지사항 상세 URL
  • 테이블 출력 방법은 두 가지를 생각함
  1. jquery 라이브러리 활용(조코딩님 유튜브 참고)
    : https://api.jquery.com/append/
  2. for 문을 활용한 동적 테이블 생성 로직
    : https://nearman.tistory.com/entry/7-동적테이블-만들기-Javascript로-동적테이블Dynamic-Table-만들기
    -> js 코드에 대한 깊은 공부를 위해 두 번째 방법을 채택하여 코드를 작성함
  • 테이블 출력 코드 작성 과정에서 현재 날짜를 지속적으로 갱신하여 요청을 보내야 하기 때문에, 현재 날짜를 받는 코드가 필요했음
    : https://hianna.tistory.com/325
  • 코드 작성 과정에서 획득한 지식
  1. var, let, const 차이점은?
    https://gist.github.com/LeoHeo/7c2a2a6dbcf80becaaa1e61e90091e5d
  2. function scope VS block scope
    https://mygumi.tistory.com/130
  3. html 안에 script 태그를 어느 위치에 삽입하는것이 가장 좋을까?
    https://dailydev.tistory.com/15
  4. HTML에서 자바 스크립트의 변수 사용
    https://m.blog.naver.com/PostView.naver?isHttpsRedirect=true&blogId=mr_chun&logNo=51962426
  5. vscode 단축키 (ctrl+k+f : 정렬, ctrl+k+c : 주석 처리, ctrl+k+u : 주석 해제)
xhr.open('GET', url + queryParams);
xhr.onreadystatechange = function () {
    if (this.readyState == 4) {
        alert('Status: ' + this.status + 'nHeaders: ' + JSON.stringify(this.getAllResponseHeaders()) + 'nBody: ' + this.responseText);
        var myArray = this.responseText;
        console.log(this.responseText);
        console.log(myArray);
        buildTable(myArray);
    }
};

xhr.send('');
console.log(xhr);
console.log(xhr.responseText);

: xhr.onreadystatechange 로 실행된 함수 내에선 xhr 객체 내용을 console로 출력할 수 있었는데, 함수 외부에선 console로 출력이 안됨.

  • 위 문제에 대해서 지인에게 자문을 구한 결과, onreadystatechange가 콜백으로 들어간 상황에서 밑의 console.log(xhr.responseText)가 실행되고 콜백함수 내부의 console.log(this.responseText)가 실행되기 때문에 전자는 출력이 안되고 후자에서 출력이 된다. 이유는 전자에서 받아온 값이 없기 때문이다.
  • 자세한 원리는 web api에서 비동기로 실행되는 함수들이 대기했다가 이벤트 큐로 이동하고, 콜스택에 차례로 쌓인 함수들이 없어져야 이벤트 큐에서 콜스택으로 함수들이 하나씩 올라가는 것이라고 한다.
  • 코드가 더 복잡해지기 전에 비동기프로그래밍과 일급객체에 대한 선행학습을 하자.
  • 비동기프로그래밍은 js에서 함수가 실행되는 시점에 대해서 공부, 일급객체를 공부하면 js에서 함수가 어떻게 사용되는지 알 수 있음.

2021. 7.30

1. 목표

  • 29일 발견된 오류의 원인을 파악하고 테이블 작성 로직을 완성
  • 비동기 프로그래밍, 콜백 함수에 대해 공부

2. 과정

  1. html에서 JS 파싱 방법
    a. head 태그에서 파싱 : JS 용량이 클 경우, 페이지 로드 시간 큼
    b. body 태그에서 파싱 : JS에 의존적인 사이트일 경우, 페이지 로드 시간 큼
    c. anync를 앞에 붙여 head 태그에서 파싱 : JS fetch가 html과 비동기적으로 끝난 후, html 파싱을 중단하여 fetch된 JS를 실행하는 방식 -> JS에서 필요한 변수가 아직 html에서 읽히지 않았을 경우, 에러 발생
    d. defer를 앞에 붙여 head 태그에서 파싱 : JS fetch는 html 파싱과 비동기적으로 이루어지고, fetch된 JS는 html 파싱이 끝난 후 이루어짐.(가장 이상적인 방식)

  2. JS 파일 상단에 'use strict'를 입력하면 엄격한 문법검사를 실행함

  3. console에 변수의 값을 출력할 때, 값이 없다면 undefined 오류메시지 출력

  4. hoisting이란? 변수나 함수가 선언된 위치 상관 없이 항상 제일 위에서 선언된 것처럼 간주됨.(자세한 개념은 더 찾아보는게 좋을듯.)

  5. constant 타입의 변수를 수정이 불가함. (멀티스레딩 코드에서 효율이 올라감, 협업시 실수를 방지함)

  6. 변수앞에 $를 붙임으로써 문자열 또는 html에서 JS 변수 참조 가능

  7. 변수에 값을 연산하여 입력할 때 (변수의 타입이 바뀌는 것 때문에 오류가 발생할 수 있음. 주의 필요)
    a. '7' + 5 : string
    b. '8' / '2' : number

  8. ==,!= : type과 reference를 고려하지 않음 (다른 공간, 다른 자료형, 같은 값일 때에도 동일 취급)

  9. ===, !== : type과 reference를 고려함 (같은 공간, 같은 자료형, 같은 값일 때 동일 취급, 주로 사용)

  10. 함수의 파라미터로 값이 들어있지 않은 변수를 넣을 때, 변수 = 문자열 형태로 입력하면 default 값인 unknown이 아닌 설정한 문자열로 인식됨.

  11. 함수의 파라미터로 ...변수 형태로 넣었을 때, 파라미터로 배열이 들어올 수 있음 (C언어에서 가변인자와 비슷)

  12. 함수를 오브젝트에 할당할 수 있고, 할당된 오브젝트를 활용하여 함수의 기능을 사용할 수 있다.

  13. 일반 함수 선언과 오브젝트에 함수를 할당하는 방식의 차이는 일반 함수 선언의 경우 hoisting 된다.

  14. arrow function의 형태 : const simplePrint = () => console.log('simplePrint!')

  15. getter는 특정변수에 대한 값을 반환, setter는 특정변수에 대한 값을 임의의 변수에 입력 (setter 사용 시 주의할 점 : 값을 가져올 변수명과 입력할 변수명을 다르게 해야한다, 무한루프 발생 가능성이 있음) -> 주로 에러처리를 위해 사용함

  16. 특정 클래스 내부에서 static으로 선언된 오브젝트는 인스턴스가 아닌 클래스명으로 직접 접근해야 함.

  17. 클래스를 선언할 때, extends 키워드를 사용하면 특정 클래스를 상속받을 수 있다.

  18. 오버라이딩 : 상위 클래스에 이미 존재하는 메소드를 재정의

  19. super는 상위클래스, this는 현재클래스를 가리킨다.

  20. instanceof 명령어?는 특정 오브젝트가 특정 클래스의 인스턴스인지 확인시켜준다.

  21. object['key'] = 'value' -> 오브젝트에 key가 존재하지 않을 경우, value를 가리키는 key를 생성한다.

  22. 클래스명과 constructor 함수명은 첫 글자가 대문자여야한다.

  23. for (key in ellie) ellie 오브젝트 안에 있는 key에 모두 접근함

  24. for (value of array) array 배열 값을 순차적으로 모두 접근

  25. 오브젝트 간에 = 로 연결하면 두 오브젝트는 하나의 reference를 가리킨다.

  26. 두 오브젝트가 다른 reference로 동일한 값을 갖고 싶을 때, 배열을 새로 하나 선언하여 값을 새로 넣는 방식과 Object.assign(new, old)를 이용하는 방법이 있다.

  27. 다수의 오브젝트를 하나의 오브젝트에 합칠 수 있는데, 다수의 오브젝트에서 중복되는 key가 존재할 경우, 마지막 인자로 입력된 key값이 적용된다.

  28. JSON.stringify : object -> json, JSON.parse : json -> object

  29. 콜백 함수란? 비동기 프로그래밍의 꽃이라고도 할 수 있는데, 특정 함수의 인자로 들어갈 수 있는 함수이고, 이를 통해 함수 내부에서 또 다른 콜백 함수가 실행될 수 있게 한다.
    : 간단한 원리는 콜백 함수를 갖고 있는 각각의 함수들이 비동기적으로 처리가 되는데, 각 콜백 함수들이 하나의 스레드로 동작(context switching)이 완료될 때까지 대기한다. 각 콜백함수의 동작이 끝나면 비로소 대기하고 있던 함수가 끝이난다.
    -> 콜백함수안의 콜백함수 구조가 이어지는 콜백 지옥을 주의해야 한다.

  30. 콜백함수를 깔끔하게 작성하기 위해 promise와 async-await가 있다. (추후에 공부 예정)

  • open API와 함께 제공된 JS 예제코드에 대해 이해하는 과정을 거쳤다.
    https://developer.mozilla.org/ko/docs/Web/Guide/AJAX/Getting_Started
  • 위의 과정과 유튜브 강의를 통해 29일 발생한 xhr.onreadystatechange = function () 내외부에서 출력되는 값의 차이의 원인을 파악하였다.
    : this.readyState가 4를 가리키고 있을 때, 서버로부터의 응답을 모두 받은 상태이고, 그 상태일 때 실행되는 함수에서는 서버로부터 데이터가 완전히 수신되어 값이 제대로 출력되는 것이 당연하지만, this.readyState가 4를 가리키고 있지 않은 상태에서 실행되는 조건문 바깥의 console.log에서는 서버로부터 데이터가 아직 완전히 수신되지 않아서 데이터가 출력되지 않는 것이다.
// 서버로 보낸 요청에 대한 응답을 받았을 때 수행할 함수
xhr.onreadystatechange = function () {
    // 4 == XMLHttpRequest.DONE
    if (this.readyState == 4) {
        var myArray = this.responseText;
        var obj = JSON.parse(myArray);
        buildTable(obj);
    }
};

// 서버에 요청 전송
xhr.open('GET', url + queryParams);
xhr.send('');
  • Uncaught SyntaxError: Unexpected token s in JSON at position 0 오류의 원인
    https://jamesdreaming.tistory.com/171
    -> 10분의 1확률, 간헐적으로 위와 같은 에러가 발생한다. 에러를 방지하거나 에러처리하는 조건문을 추가해야할 것 같다.

  • 에러메시지

  • 에러가 발생했을 때 받은 xhr.responseText

  • 정상일 때 받은 xhr.responseText

  • html 태그 <td>와 <th>의 차이
    : <td>는 테이블 안의 값을 진하게 출력, <th>는 테이블 안의 값을 보통으로 출력

  • table 태그의 속성 알아보기
    https://amy82.tistory.com/137
    https://aboooks.tistory.com/59

  • 결과화면 (뿌~듯)

  • Next

  1. 현재 10개의 list만 받아오는데, 요청으로 보낸 기간에 해당하는 list를 모두 받아서 탭으로 10개씩 넘길 수 있는 형태로 테이블을 만들 것이다.
  2. 자세히 보기의 url로 접속 가능한 버튼을 만들 것이다.
  3. 웹사이트를 보기좋은 형태로 다듬자.

2021. 8. 4.

  • 7.30.에 언급했던 error response에 대한 처리를 추가하였다.
    : error response 텍스트의 첫번째 인덱스는 항상 s라는 점을 이용하여 if 조건문을 통해 분기시켰고, 첫번째 인덱스가 0일 때 사용하고 싶은 텍스트의 시작점인 454인덱스부터 마지막까지 tmp 매개변수에 새로 입력하여 사용하였다.
// 서버로 보낸 요청에 대한 응답을 받았을 때 수행할 함수
xhr.onreadystatechange = function () {
    // 4 == XMLHttpRequest.DONE
    if (this.readyState == 4) {
        var myArray = this.responseText;
        if (this.responseText[0] == "s")
        {
            let tmp = myArray.substr(454, myArray.length);
            var obj = JSON.parse(tmp);
        }
        else
            var obj = JSON.parse(myArray);
        buildTable(obj);
    }
};

2021. 8.12.

2021. 8.14.

  • html 양식 빠르게 만들기 : ! + tab

  • 오늘은 paging 기능을 구현하였다.

  • 참고한 사이트
    pagination.js : https://pagination.js.org/
    pagination.js 기본 예제 : https://junho85.pe.kr/1440
    js Array forEach : https://yuddomack.tistory.com/entry/자바스크립트-Array-forEach
    요소의 속성 값을 가져오는 메소드 .getAttribute() : https://www.codingfactory.net/10283
    메뉴 구현할 때 필요한 Navigation Bar : https://m.blog.naver.com/PostView.naver?isHttpsRedirect=true&blogId=znsl0326&logNo=221425011251
    html div 태그 : https://coding-factory.tistory.com/188
    html form 태그 : https://ofcourse.kr/html-course/form-%ED%83%9C%EA%B7%B8
    div 태그 속성 : https://dever.tistory.com/232
    div와 span 태그 차이 : https://mainia.tistory.com/3289
    html button 태그 : https://opentutorials.org/course/1058/4802
    html button 태그 : https://aboooks.tistory.com/301
    button 태그 onClick으로 페이지 이동 : https://yeoninim.tistory.com/26
    html input 태그 : https://aboooks.tistory.com/294
    a태그 대신 onclick=location.href 활용하기 : https://designalen.tistory.com/22

  • google 페이지가 html 코드로 어떻게 구성되어 있는지도 참고하였다.

  • google 페이지에서 paging 방식은 a 태그를 활용하여 링크로 연결시켜주는 방식이었다.

  • 페이지 번호를 누를 때마다 api요청을 다르게 보내야 하고, 받은 응답을 가공하여 테이블로 출력해야하기 때문에 부적절한 방식이었다.

  • 중간에 api요청으로 페이지 번호를 주면, 페이지 번호에 맞게 데이터 응답이 온다는 사실을 알게 되었다.

  • 처음에 생각한 방식은 버튼마다 어떤 번호인지 알려주는 value를 js에 전달하여 page 번호로 api 요청을 보낼 생각이었는데, value를 어떻게 js에 전달해야할 지 감이 안왔다.

  • 그러는 와중에 밑의 글을 보게 되었다.
    자바스크립트 기반의 pagination 만들기 : https://smilerici.tistory.com/34

  • 위의 글은 고정된 배열 값을 테이블로 출력하는데, paging 기능을 추가하여 페이지마다 3개씩 테이블 형태로 출력하는 코드를 소개하였다.

  • js 코드에 renderTable, renderPagination, addEventPagination 세 개의 함수로 구성되어 있다.

  • renderTable은 html 테이블의 id를 객체로 받아서 해당 객체에 html 코드형태의 문자열을 담는 코드이다. 고정으로 선언된 배열 값을 하나씩 참조하여 html 코드를 구성하였다. 페이지 번호를 인자로 받아서 페이지 번호에 맞는 원소를 테이블로 출력해준다.

  • renderPagination은 html div태그의 id를 객체로 받아서 해당 객체에 paging 테이블을 보여주는 html 코드형태의 문자열을 담는 코드이다. 페이지 번호를 인자로 받아서 페이지 번호에 맞게 번호에 style을 부여하고 번호와 next, ...last, Prev, first...와 같은 버튼을 활성화 한다.

  • addEventPagination은 페이지 번호를 눌렀을 때, 클릭된 번호의 class에 따라 page번호를 정하고, 정해진 page 번호를 인자로 입력하여 renderTable과 renderPagination 함수를 실행하는 함수이다. document.querySelector 메소드로 어떤 클래스의 버튼이 눌려졌는지 판단한다. querySelector 메소드에 대해 더 알아보면 좋을 것 같다.

  • 이제 위 코드를 내 코드에 적용시켜야 한다.

  • 테이블을 그려주는 함수는 내가 구현한 buildTable을 그대로 이용하기로 하였다.

  • renderPagination과 addEventPagination함수만 이용하여 내 코드에 적용할 것이다.

  • 적용방안

  1. 기존에 요청으로 보낼 url을 구성하여 api 요청을 보내고 응답을 받는 코드를 getApi함수로 구성하였다.
  2. 응답을 받았을 때, renderPagination 함수를 실행시키도록 하였다. (renderPagination 마지막에 addEventPagination함수 역시 실행한다.)
  3. addEventPagination 함수에서 class 옵션에 따라 renderTable과 renderPagination 함수를 실행했던 것을 getApi함수를 실행시키도록 하였다. (page번호가 getApi 함수의 인자로 pageReq로서 입력되었고, pageReq를 api 요청으로 보내어 응답으로 받는다. pageReq의 default 값은 1이다.)
  4. 마지막 페이지는 게시글이 10개라는 보장이 없기 때문에, getApi 함수에서 응답을 받았을 때, 마지막 페이지일 경우, 마지막 페이지의 게시글 갯수를 계산하여 갯수대로 테이블을 구성하는 조건문을 추가하였다.

0개의 댓글