[TIL : 19] 비동기, Node.js 모듈

jabae·2021년 11월 9일
0

TIL

목록 보기
19/44

Achievement Goals

  • 어떤 경우에 중첩된 callback이 발생하는지 이해할 수 있다.

    클라이언트와 서버가 비동기적으로 여러가지 일을 수행하게 하기 위해서(예를 들면 유튜브 영상의 로딩을 기다리면서 댓글을 보거나 좋아요를 누르거나 추천 영상을 보거나 ... 이렇게 여러가지 일은 하는 것!), 콜백을 계속 부르게 되면 중첩이 된다.
    콜백... 콜백... 콜백... 함수 안에서 계속 콜백을 외치게 되면 함수도 알아보기 어렵게 복잡해지고 수정보완도 어려워지는데, 이를 callback Hell이라고 한다.

  • 중첩된 callback의 단점, Promise의 장점을 이해할 수 있다.

    따라서 위의 예시를 피하기 위해 Promise를 사용한다. Promise를 사용하면 함수의 사용이 플랫해지면서 단순하고 알아보기가 쉬워진다. 아래 예시를 보면 알 수 있다.

    const printString = (string, callback) => {
        setTimeout(() => {
        console.log(string)                     // string 프린트
        callback()                              // 함수 실행
        }, Math.floor(Math.random() * 100) + 1) // 랜덤 시간 주어짐
        }
    
    const printAll = () => {
        printString("A", () => {
            printString("B", () => {
                printString("C", () => {
                })
            })
        })

    이렇게 중첩 callback을 써야 차례로 A B C 를 프린트할 수 있다. 반면 Promise는

    const printString = (string => {
        return new Promise ((resolve) => {
        setTimeout(() => {
            console.log(string)                     // string 콘솔에 출력
            resolve()                               // .then 실행
            }, Math.floor(Math.random() * 100) + 1) // 랜덤 시간 주어짐
            })
        }
    
    const printAll = () => {
        printString("A")
        .then(()=> {
            return printString("B")     // A를 출력한 다음 실행한다.
        })
        .then(()=> {
            return printString("C")     // B를 출력한 다음 실행한다.
        })

    이렇게 플랫하게 순서를 알기도 쉽게 사용할 수 있다.

  • Promise 사용 패턴을 이해할 수 있다.

    yes! 🙌

  • resolve, reject의 의미와, then, catch와의 관계를 이해할 수 있다.

    resolve : promise의 매개변수 중 하나로 resolve를 호출하면 .then()이 실행된다.
    reject : promise의 매개변수 중 하나로 reject를 호출하면 .catch()가 실행된다.
    .then() : resolve에서 인자를 받아 실행된다.
    .catch() : reject에서 인자를 받아 실행된다.
    쉽게 말해서 성공시 resolve -> .then() 실패, 에러시 reject -> .catch() 순서이다.

    let state = true; // true -> resolve
    const promiseTest = new Promise( (resolve, reject) => {
        if(state){
            resolve('success');
        }else{
            reject('Error');
        }
    });
    
    promiseTest
        .then( (result) => {
            console.log(result); // resolve()에서 받아 실행
        })
        .catch( (error) => {
            console.error(error); // reject()에서 받아 실행
    });
    // 결과로 success 가 콘솔에 뜨게 된다.
  • Promise에서 인자를 넘기는 방법을 이해할 수 있다.

    yes! 👍

  • Promise의 세 가지 상태를 이해할 수 있다.

    Pending : 요청된 동작이 완료되지 않은 상태
    Fulfilled : 요청된 동작이 완료되어 Promise가 결과 값을 반환 resolve -> .then()
    Rejected : 요청된 동작이 실패하거나 오류가 발생한 상태 reject -> .catch()

  • Promise.all 의 사용법을 이해할 수 있다.

    매개변수를 배열로 받아 주어진 Promise를 모두 이행한다. 위의 예시를 활용해보자.

    const promiseTest = (state) => {
        return new Promise( (resolve, reject) => {
        if(state){
            console.log(state)       // 차례로 one two three 가 콘솔에 출력된다.
            resolve(state);
        }else{
            reject('Error');
        }
    });
    }
    
    let state1 = promiseTest('one');
    let state2 = promiseTest('two');
    let state3 = promiseTest('three');
    
    Promise.all([state1, state2, state3])
        .then( (values) => {
            console.log(values);    // 배열 ['one', 'two', 'three']가 출력된다. 
        })
        .catch( (error) => {
            console.log(error); 
    });

    위의 예시를 실행하면
    one two three
    ['one', 'two', 'three']
    Promise {: undefined} 가 출력된다. Promise.all을 통해 배열로 넣어준 인자를 다 돈다.

  • async/await keyword에 대해 이해하고, 작동 원리를 이해할 수 있다.

    async/await의 사용은 이해한다면 더 쉽다. 콜백함수와 프로미스의 단점을 보완했다.

      const promiseTest = (state) => {
        return new Promise( (resolve, reject) => {
        if(state){
            console.log(state)
            resolve(state);
        }else{
            reject('Error');
        }
    });
    }
    
    const testTest = async() => {
    const state1 = await promiseTest('one');
    const state2 = await promiseTest('two');
    const state3 = await promiseTest('three');
    }
    
    testTest();

    마치 동기함수처럼 훨씬 깔끔하고 가독성있다. 함수에 쓸 때 async function 함수이름() {...} 이렇게 쓰면 된다.

  • Node.js의 fs 모듈의 사용법을 이해할 수 있다.

    require를 이용해 최상단에 모듈을 불러와야 한다. 이후 사용하면 된다.

    const fs = require('fs')                              // 최상단에 모듈을 불러오기
    
    fs.readFile('something.txt', 'utf8', (err, data) => {  //사용!
    	if (err) {
        	  throw err;
              }
              console.log(data);)
              });

    참고로 fs.readFilefs.readFile(읽을파일, 옵션, 콜백함수)로 쓰인다. 옵션은 인코딩방식을 넘기고 안 쓸 수도 있다.

  • 3rd-party 모듈 사용하기

    npm install 사용할모듈 으로 사용전 터미널에서 깔아주면 된다. 이후 Node.js의 내장 모듈처럼 js파일 안 최상단에 require으로 불러와 사용하면 된다.

그 외

  • 이번에 프로젝트를 시작하면서 백엔드와 협업을 하기 위해서 앞에 진도를 건너 뛰고 비동기를 먼저 배우게 되었다. 흠... 첨엔 생소하고 어색해서 어걸 대체 어떻게 사용하는거지?!?! 했는데 저렇게 몇 번 써보고 직접 예시도 만들어보니 작동 방식을 알게 된 것 같아서 뿌 --- 듯 😆
  • 여태까지 복잡한 식을 만들지 않고, 읽어올 파일도 다 js로 가공된(?) 자료들을 갖다가 썼는데 정말정말 백엔드와 협업하기 위해서는 API도 읽을 줄 알아야하고, 복잡한 함수보다는 다른 사람과도 소통해야 하기 때문에 읽기 쉽게 만들기도 해야한다. 내가 해야할 일도 많아질 것 같다 😆😆😆😱
profile
it's me!:)

0개의 댓글