개발일지 Dev Diaries/항해99 Hanghae99

[항해99 27일차] (22.04.02) 자바스크립트/리액트 파고들기

이땡칠 2022. 4. 3. 22:35

어제 밤까지 자바스크립트 비동기 처리를 파고들다가, 체력의 한계가 와서 잠들었다.

오전 중에 promise, async/await 의 개념을 이해하고

오후에는 본격 리액트 파고들기를 해보려고 한다.

 

 

오늘 배운 것

1. 자바스크립트 비동기 처리

1) Callback

  • 콜백 지옥 
    • 콜백함수는 특정 함수에 매개변수로 전달된 함수를 의미한다. 그 콜백함수는 함수를 전달받은 함수 안에서 호출된다. 
    • 콜백지옥은 JavaScript를 이용한 비동기 프로그래밍시 발생하는 문제로서, 함수의 매개변수로 넘겨지는 콜백함수가 반복되어 코드의 들여쓰기 수준이 감당하기 힘들 정도로 깊어지는 현상을 말한다. 
    • 예제
step1(function (value1) {
    step2(function (value2) {
        step3(function (value3) {
            step4(function (value4) {
                step5(function (value5) {
                    step6(function (value6) {
                        // Do something with value6
                    });
                });
            });
        });
    });
});

step1에서 어떤 처리 (주로 입출력) 이후 그 결과를 받아와, 인자로 전달된 익명 함수의 매개변수로 넘겨준다. 이후 step2에서 또 어떤 처리를 하고, 다음 익명 함수가 실행된다. 이를 반복하다보면 코드가 위에서 아래가 아니라 기묘한 피라미드 모양으로 기술되게 된다. 여기서 에러 처리가 포함되면 더욱 가관이다.

 

  • 이런 콜백 헬이 발생하는 이유?
    • 비동기 처리 시에는 실행 완료를 기다리지 않고 바로 다음 작업을 실행한다.
    • 즉, 순서대로 코드를 쭉 적는다고 우리가 원하는 순서로 작업이 이뤄지지 않는다.
    • 비동기 처리 함수 내에서 처리 결과를 반환하는 걸로는 원하는 동작을 하지 않으니, 콜백 함수를 사용해 원하는 동작을 하게 하려고 콜백 함수를 쓰게된다.
    • 이 콜백 함수 내에서 또 다른 비동기 작업이 필요할 경우 위와 같은 중첩이 생기면서 콜백 지옥이 탄생한다.
  • 콜백함수의 문제점 
    • 코드가 너무 복잡해진다. 
    • 오류 발생 시 오류부분을 확인하기 어렵다.

 

2) Promise

  • Promise
    • Promise 는 비동기 연산이 종료된 이후 결과를 알기 위해 사용하는 객체이다.
    • 프로미스를 쓰면 비동기 메서드를 마치 동기 메서드처럼 값을 반환할 수 있다.
  • 프로미스 생성
    • 프라미스는 Promise 생성자 함수(new 키워드 기억하시죠!)를 통해 생성합니다.
    • 비동기 작업을 수행할 콜백 함수를 인자로 전달받아서 사용합니다.

 

// 프라미스 객체를 만듭니다. 
// 인자로는 (resolve, reject) => {} 이런 excutor 실행자(혹은 실행 함수라고 불러요.)를 받아요.
// 이 실행자는 비동기 작업이 끝나면 바로 두 가지 콜백 중 하나를 실행합니다.
// resolve: 작업이 성공한 경우 호출할 콜백
// reject: 작업이 실패한 경우 호출할 콜백
const promise = new Promise((resolve, reject) => {
	if(...){
		...
		resolve("성공!");
	}else{
		...
		reject("실패!");
	}
});

 

  • 프로미스의 상태값
    • pending: 비동기 처리 수행 전(resolve, reject가 아직 호출되지 않음)
    • fulfilled: 수행 성공(resolve가 호출된 상태)
    • rejected: 수행 실패(reject가 호출된 상태)
    • settled: 성공 or 실패(resolve나 reject가 호출된 상태
  • 프로미스 후속 처리 메서드 
    • 프라미스로 구현된 비동기 함수는 프라미스 객체를 반환하죠!
    • 프라미스로 구현된 비동기 함수를 호출하는 측에서는 이 프라미스 객체의 후속 처리 메서드를 통해 비동기 처리 결과(성공 결과나 에러메시지)를 받아서 처리해야 합니다.
    • .then(성공 시, 실패 시) 
      • then의 첫 인자는 성공 시 실행, 두번째 인자는 실패 시 실행됩니다. 
// 프라미스를 하나 만들어 봅시다!
let promise = new Promise((resolve, reject) => {
	setTimeout(() => resolve("완료!"), 1000);
});

// resolve
promise.then(result => {
	console.log(result); // 완료!가 콘솔에 찍힐거예요.
}, error => {
	console.log(error); // 실행되지 않습니다.
});
// 프라미스를 하나 만들어 봅시다!
let promise = new Promise((resolve, reject) => {
	setTimeout(() => reject(new Error("오류!")), 1000);
});

// reject
promise.then(result => {
	console.log(result); // 실행되지 않습니다.
}, error => {
	console.log(error); // Error: 오류!가 찍힐거예요.
});

 

 

2. 토큰 기반 인증

1) OAuth2.0

  • 외부 서비스의 인증 및 권한부여를 관리하는 프레임워크
  • OAuth 동작 방식 (간단 ver.)
    1. 클라이언트와 서버 사이엥 인증(로그인)을 하면 서버가 access_token 을 줌
    2. 클라이언트는 access_token 을 이용해서 API 요청을 할 수 있음
    3. 서버는 ApI 요청을 받고, access_token 을 가지고 권한이 있나 없나 확인해서 결과를 클라이언트에게 보내줌
  • OAuth 동작 방식 (구글 로그인 서비스 엮음 ver.)
    1. 유저 구글 로그인
    2. 구글은 유저가 입력한 로그인 정보를 보고 클라이언트(우리 웹사이트)에 접근 권한을 줌
    3. 클라이언트는 이 권한을 가지고 Authorization server(권한 서버)에 access_token 을 요청
    4. 클라이언트는 이 access_token 을 가지고 구글에서 유저 정보를 가져올 수 있음
    5. 구글은 클라이언트가 보낸 access_token 을 가지고 권한 유무를 확인, 결과를 클라이언트에게 보내줌

 

2) JWT(Json Web Token)

 

 

3. 웹 저장소

1) 클라이언트 저장소

  • 개발자도구 → Application 탭 → 좌측 Storage

2) 쿠키

  • 클라이언트 로컬에 저장되는 key:value 형태의 저장소
  • 약 4KB 정도 저장 가능
  • 쿠키 만들기
// key는 MY_COOKIE, value는 here, 
document.cookie = "MY_COOKIE=here;";
  • 쿠키 가져오기
console.log(document.cookie);
  • 쿠키 삭제
    • 쿠키를 삭제할 때는 만료일을 이전으로 돌려서 지우는 방법을 많이 씁니다.
document.cookie = "MY_COOKIE=here; expires=new Date('2020-12-12').toUTCString()";

 

3) 세션 스토리지

  • HTML5에서 추가된 저장소
  • 쿠키와 마찬가지로 key:value 형태의 저장소
  • 세션 스토리지에 저장된 데이터는 브라우저를 닫으면 제거됨
  • 자동 로그인이나, 장바구니같은 다음에 브라우저를 열었을 때도 유지해야하는 데이터는 넣기 어려움
  • 추가하기
// key는 MY_SESSION, value는 here인 세션을 만들어요.
sessionStorage.setItem("MY_SESSION", "here");
  • 가져오기
// key값으로 쉽게 가져올 수 있어요 :) 
sessionStorage.getItem("MY_SESSION");
  • 삭제하기
// 하나만 삭제하고 싶다면, 이렇게 키를 통해 삭제합니다.
sessionStorage.removeItem("MY_SESSION");

// 몽땅 지우고 싶을 땐 clear()를 쓰면 됩니다. :) 
sessionStorage.clear();

 

4) 로컬 스토리지

  • HTML5에서 추가된 저장소
  • 쿠키와 마찬가지로 key:value 형태의 저장소
  • 로컬 스토리지는 따로 지워주지 않으면 계속 브라우저에 남아 있음
  • 유저의 아이디, 비밀번호같은 중요한 정보를 넣어두면 아주 위험함

 

 

  • 추가하기
// key는 MY_LOCAL, value는 here인 데이터를 저장해요.
localStorage.setItem("MY_LOCAL", "here");
  • 가져오기
// key값으로 쉽게 가져올 수 있어요 :) 
localStorage.getItem("MY_LOCAL");
  • 삭제하기
// 하나만 삭제하고 싶다면, 이렇게 키를 통해 삭제합니다.
localStorage.removeItem("MY_LOCAL");

// 몽땅 지우고 싶을 땐 clear()를 쓰면 됩니다. :) 
localStorage.clear();

 

 

회고 

1. 어제에 이어서 컴포넌트 쪼개기와 로그인 기능을 공부하다가 공부를 종료했다. 컨디션이 좋지 않아서 많은 량의 공부를 하지 못했는데.. 주말을 잘 마무리하고 다음주부터는 지금보다 더 컨디션 관리를 잘 해야겠다. 

 

2. 공부시간 중 제대로 집중하고 몰입하지 못하는 시간들이 있다. 이 시간들을 잘 활용해야 주어진 과제를 마칠 수 있겠다는 생각이 든다. 집중, 집중, 집중!

 

3. 컴포넌트 쪼개기 부분은 생각보다 어려웠다.

 - 컴포넌트에 디폴트Props 로 무엇을 줘야 하는지, 

 - 어떤 기준으로 컴포넌트를 나누고, 

 - 각 컴포넌트에 props 로 뭘 넘겨줘야, 데이터별/뷰별로 만든 컴포넌트를 잘 활용할 수 있을지 등

 

아직은 익숙하지 않은 것들이 많다. 개념적인 이해가 충분히 필요하다. 

 

4. 강의를 모두 들어야한다는 느낌보다는 강의자료를 쓱 훑어보고, 필요한 강의를 챙겨듣는다는 마인드로 접근해야겠다. 단순히 1강, 1강 듣는다는 느낌으로 접근하면 필요한 것을 제대로 익히기 어렵다.