상권's

TIL 9 (2021.10.15) 본문

~2022 작성 글/TIL

TIL 9 (2021.10.15)

라마치 2021. 10. 15. 19:06

Redux는 자바스크립트 앱을 위한 예측 가능한 상태 컨테이너입니다. -> 상태 관리 라이브러리

 

Redux는 여러분이 일관적으로 동작하고, 서로 다른 환경(서버, 클라이언트, 네이티브)에서 작동하고, 테스트하기 쉬운 앱을 작성하도록 도와줍니다. 여기에 더해서 시간여행형 디버거와 결합된 실시간 코드 수정과 같은 훌륭한 개발자 경험을 제공합니다.

여러분은 Redux를 React나 다른 뷰 라이브러리와 함께 사용할 수 있습니다. Redux는 매우 작지만(의존 라이브러리 포함 2kB), 사용 가능한 애드온은 매우 많습니다.

 

=> Redux는 state를 관리해주는데, 부모와 자식, 손주들 간에 state에 물려받고, 변경하는 일이 발생을 하게 되면은 선언했던 컴포넌트까지 찾아가야 되서 어려움이 따를 수 밖에 없다. 근데 리덕스를 통해서 store라는 곳에 state를 넣어서 어떤 컴포넌트에서 변경이 발생하더라도 금방 찾아서 처리가 될 수 있게 도와준다.

 


출처 MDN

Array.prototype.flat()

flat() 메서드는 모든 하위 배열 요소를 지정한 깊이까지 재귀적으로 이어붙인 새로운 배열을 생성합니다.

const newArr = arr.flat([depth])

depth [Optional] = 중첩 배열 구조를 평탄화할 때 사용할 깊이 값. 기본값은 1입니다.

반환 값

하위 배열을 이어붙인 새로운 배열.


비동기처리를 동기처리로 진행하는 3가지 방법.

callback, promise, async/await! 

callback

const printString = (string, callback) => {
    setTimeour(
        () => {
            console.log(string)
            callback()
        },
        1000
    )
}

const printAll = () => {
    printString('A', () => {
        printString('B', () => {
            printString('C', () => {})
        })
    })
}

만약에, 일정한 시간 이후에 1이 실행되고, 또 일정한 시간 이후에 2가 실행이 되고 ...

이러한 상황이 있다고 가정하겠습니다. task의 처리는 동기적으로 처리가 되어야 합니다.

callback함수를 이용해서 해당 함수가 끝을 보게 되면, 두번 째 인자로 받은 함수가 실행됨으로써 동기적으로 처리를 할 수 있습니다.

 

이렇게 callback함수가 계속해서 이어지면 결국은 > 이러한 모양을 띄게 되는 데, 이럴 경우 코드가 직관적이지 못합니다. 이처럼 계속해서 callback함수가 이어지는 것을 callback hell이라고 합니다.

promise

const getDataFromFilePromise = filePath => {

  let options = {
    encoding: 'utf8',
    flag: 'r'
  }

  return new Promise ((resolve, reject) => {
    fs.readFile(filePath, options, (err, data) => { // fs.readFile의 세번째 인자로 함수를 받게 되는데,
      if(err) { // 만약 에러라면 
        reject(err) // reject를 통해서 err를 나타내고,
      }
      else { // 에러가 아니라면
        resolve(data) // data를 전달한다.
      }
    })
  })

  // TODO: Promise 및 fs.readFile을 이용해 작성합니다.
};

const readAllUsersChaining = () => {
  let arr = []
  return getDataFromFilePromise(user1Path)
  .then( (data) => { // getDataFromFilePromise(user1Path)가 정상적으로 작동이 되면 만들어지는 파일이 data
    let dataObject = JSON.parse(data) // data를 parse 해준다.
    return dataObject}) // parse한 데이터를 리턴한다. => 프로미스를 리턴하면 프로미스가 나온다.
    .then ( (dataObject) => { //=> 파일을 arr에 넣어준다. - user1Path 에 대한 처리는 끝!
      arr.push(dataObject)
      return getDataFromFilePromise(user2Path)}) // 다음으로 getDataFromFilePromise(user2Path) 진행한다.0 
      .then ((data1) => { // 정상적으로 작동이 되어서 data1이 나온다.
        let dataObject1 = JSON.parse(data1) // data1을 parse 하고
        arr.push(dataObject1) // arr에 푸쉬한다.
        return arr
      })
}

promise => then 을 이용해서, promise함수가 성공적으로 처리가 되면, 또 함수를 호출해서 다음으로 task를 처리할 수 있습니다. then 을 통해서 resolve()의 처리를 진행할 수 있습니다.

 

만약에 promise와 then 이 많아질 경우 이또한 callback hell과 똑같은 모습을 띌 수 있습니다.

  return getDataFromFilePromise(user1Path)
  .then( (data) => {
    let dataObject = JSON.parse(data)
    arr.push(dataObject)
    return getDataFromFilePromise(user2Path)})
  .then ( (data) => {
    let dataObject = JSON.parse(data)
    arr.push(dataObject)
    return arr;
  }) 
}

 

이처럼 계속해서 내부에서 then 과 return 을 반복하지 않고, return 새로운 함수를 하고 해당 then 을 끝내고 난 뒤, 거기에 대한 then 을 함으로써 정리할 수 있습니다. promise then 을 하게 되면 promise 객체를 생성해서 리턴하기 때문에 또 then 을 이용할 수 있습니다.

 

이렇게 then 으로 promise 객체가 이어지는 걸 chaining 이라고 합니다.

이처럼 정상적으로 실행되는 것은 then으로 이어질 수 있는데, 중간에 에러가 발생해서 reject가 실행 되어야 할 경우에는 .catch를 통해서 표현할 수 있는데, 이 경우에는 chain의 맨 마지막에 .catch 적어줌으로써, failure task를 정의할 수 있습니다.

async/await

const readAllUsersAsyncAwait = async () => { // async 함수를 통해서 promise 함수 앞에 await을 추가해서 실행하게 되면,
  let result = []                            // 동기적으로 함수를 진행할 수 있다. 
  await getDataFromFilePromise(user1Path)
  .then( (data)=> {
    result.push(JSON.parse(data)) })
  await getDataFromFilePromise(user2Path)
  .then((data) => {
     result.push(JSON.parse(data))
    })
   return result
}

async 함수를 만들어서 await을 활용하면 순차적으로 함수가 실행되기 때문에 동기적으로 task를 처리할 수 있습니다.

 

=> 현재 세 가지 방법에 대해서 이해는 하고 있지만 ,아직 손에 익질 않아서 지속해서 학습하면서 익숙해질 수 있도록 노력해야겠습니다.

 

SyntaxError: Unexpected token o in JSON at position 1

이러한 에러가 발생할 경우에는, 이는 자바스크립트 객체에다가 JSON.parse를 사용할 경우 이러한 에러가 확인됩니다.

=>  fetch를 이용해서 response 에다가 .json() 을 해주고 난 뒤 JSON.parse 를 쓰니 이런 에러가 나서 알게 되었습니다.


출처 위키백과

 

API란,

API(Application Programming Interface 응용 프로그램 프로그래밍 인터페이스) 응용 프로그램에서 사용할 수 있도록, 운영 체제 프로그래밍 언어가 제공하는 기능을 제어할 수 있게 만든 인터페이스를 뜻한다.

주로 파일 제어, 창 제어, 화상 처리, 문자 제어 등을 위한 인터페이스를 제공한다.


타이머 관련 API

setTimeout(callback, millisecond)

일정 시간 후에 함수를 실행

arguments: 실행할 callback 함수, callback 함수 실행 전 기다려야 할 시간 (밀리초)

return value: 임의의 타이머 ID

 

setInterval(callback, millisecond)

일정 시간의 간격을 가지고 함수를 반복적으로 실행

arguments: 실행할 callback 함수, 반복적으로 함수를 실행시키기 위한 시간 간격 (밀리초)

return value: 임의의 타이머 ID

 

clearInterval(timerId)

반복 실행중인 타이머를 종료

arguments: 타이머 ID

return value: 없음


출처 MDN

 

Fetch API를 이용하면 Request나 Response와 같은 HTTP의 파이프라인을 구성하는 요소를 조작하는것이 가능합니다. 또한 fetch() (en-US) 메서드를 이용하는 것으로 비동기 네트워크 통신을 알기쉽게 기술할 수 있습니다.

 

이전에 이러한 기능을  XMLHttpRequest에서 제공하고 있었습니다. Fetch는 이러한 API의 대체제로 Service Workers (en-US)같은 기술로 간단히 이용하는것이 가능합니다. 또한 CORS나 HTTP확장같은  HTTP에 관련한 개념을 모아 정의하고 있습니다.

Fetch의 기본 스펙은jQuery.ajax()와 기본적으로 두가지가 다르다는 사실에 유념해야합니다.

 

fetch()로 부터 반환되는 Promise 객체는 HTTP error 상태를 reject하지 않습니다. HTTP Statue Code가 404나 500을 반환하더라도요. 대신 ok 상태가 false인 resolve가 반환되며, 네트워크 장애나 요청이 완료되지 못한 상태에는 reject가 반환됩니다.

 

보통 fetch는 쿠키를 보내거나 받지 않습니다.  사이트에서 사용자 세션을 유지 관리해야하는 경우 인증되지 않는 요청이 발생합니다. 쿠키를 전송하기 위해서는 자격증명(credentials) 옵션을 반드시 설정해야 합니다.
2017년 8월 25일 이후. 기본 자격증명(credentials) 정책이 same-origin 으로 변경되었습니다. 파이어폭스는 61.0b13 이후 변경되었습니다.

 

기본적인 fetch는 누구라도 알기쉽고 간단하게 작성할 수 있습니다. 아래의 코드를 봐주시기 바랍니다.

fetch('http://example.com/movies.json') 
	.then(function(response) { 
		return response.json(); 
    }) 
	.then(function(myJson) {
    	console.log(JSON.stringify(myJson)); 
    });

네트워크에서 JSON 파일을 가져 와서 콘솔에 인쇄합니다. 간단한 fetch() 사용 흐름은 인수 한개(가져올 자원의 경로)를 가져오고 응답을 포함하는 약속 (Response (en-US) 개체)을 반환하는 것입니다.

이것은 단순한 HTTP Response이며, 실제 JSON이 아닙니다. response 객체로부터 사진을 가져오기 위해서는 json() (en-US) 메서드를 사용할 필요가 있습니다. (Body의 믹스인 (역주:php의 트레이드와 같은것입니다. )으로 정의되어, 이것은 Request 객체와 Response (en-US) 객체의 쌍방에 구현되어 있습니다.


구조 분해 할당은 Spread 문법을 이용하여 값을 해체한 후, 개별 값을 변수에 새로 할당하는 과정을 말합니다.

분해 후 새 변수에 할당

배열

const [a, b, ...rest] = [10, 20, 30, 40, 50];

// 질문: a, b, rest는 각각 어떤 값인가요?
a //10
b //20
rest //[30, 40, 50]

객체

const {a, b, ...rest} = {a: 10, b: 20, c: 30, d: 40} 
// 질문: a, b, rest는 각각 어떤 값인가요?
a //10
b //20
rest //{c: 30, d: 40}
  • 객체에서 구조 분해 할당을 사용하는 경우, 선언(const, let, var)과 함께 사용하지 않으면 에러가 발생할 수 있습니다.
  • 선언없이 할당하는 경우, 이 콘텐츠의 하단있는 공식문서 링크를 통해 내용을 확인할 수 있습니다.

예제

function whois({displayName: displayName, fullName: {firstName: name}}){
  console.log(displayName + " is " + name);
}

let user = {
  id: 42,
  displayName: "jdoe",
  fullName: {
      firstName: "John",
      lastName: "Doe"
  }
};


whois(user) // jdoe is John

아직은 잘 활용하지는 못하겠지만 추가적인 학습을 통해서 익숙해질 수 있도록 노력하겠습니다.

MDN 구조분해할당

'~2022 작성 글 > TIL' 카테고리의 다른 글

TIL 11 (2021.10.17)  (0) 2021.10.17
TIL 10 코드 리뷰 (2021.10.08)  (0) 2021.10.16
TIL 8 (2021.10.14)  (0) 2021.10.14
TIL 7 코드 리뷰 & 리팩토링 (2021.10.13)  (0) 2021.10.13
TIL 7 (2021.10.13)  (0) 2021.10.13
Comments