Post

[JavaScript] 복습 2

[JavaScript] 복습 2

데브자스

JavaScript 개념

스코프 scope

  • 변수에 접근할 수 있는 유효한 범위

렉시컬 스코프 lexical scope

  • 코드 위치에 따라 한 실행 컨텍스트에서 유효한 범위
  • 작성 시점에 스코프가 결정됨.

렉시컬 환경 lexical environment

  • 실행 컨텍스트의 recordouter를 아우르는 말

    Image


eslint 세팅

  • 자바스크립트의 문법적인 오류를 검사한다.
  1. eslint 패키지 설치

    Image

    1
    
     npm install eslint
    
  2. eslint 초기 설정
    eslint.config.mjs 파일 생성

    Image

    1
    
     npm eslint --init
    

    Image
    → To check syntax and find problems

    Image
    → JavaScript modules

    Image
    → None of these

    Image
    → No

    Image
    → No

    Image
    생성 확인!



JavaScript 콜백, 프로미스, async await

콜백 함수

  • 다른 함수에 인수로 전달되어 나중에 호출되는 함수
  • 어떤 작업이 끝나면, 그 다음 작업을 하도록 나중에 호출됨

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    
      function greet(name, callback) {
        console.log("안녕하세요, " + name + "님!");
        callback();
      }
        
      function afterGreeting() {
        console.log("방문해 주셔서 감사합니다.");
      }
        
      greet("이재건", afterGreeting);
    

콜백 지옥

  • 많은 콜백함수를 중첩되어 사용하면서,
    코드가 복잡해지고 가독성이 떨어지게 됨

Promise

Image

  • 자바스크립트의 비동기 작업을 처리하기 위한 객체
  • ‘나중에 결과가 올 것이다’ 약속하는 객체
  • 3가지의 PromiseState: Pending → fullfiled, rejected 존재
  • Producer vs Consumer 관계로 설정

  • pending
    • 프로미스 객체가 생성된 즉시 → 대기 중, 아직 결과가 없음
  • fullfilled
    • 작업이 성공, resolve가 호출된 상태
  • rejected
    • 작업이 실패, reject가 호출된 상태

  • then
    • 성공 시, 실행할 코드
  • catch
    • 실패 시, 실행할 코드
  • finally
    • 작업 성공/실패 여부 상관 없이, 실행할 코드

  • 사용 방법
    참고: 가독성을 위해, 별도로 // 주석 표시를 진행.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    
      // Promise - Producer
      const promise = new Promise((resolve, reject) => {
        const success = true;
        
        if (success) {
          resolve("실행 성공!");
        } else {
          reject("실행 실패!");
        }
      });
        
      // Promise - Consumer
      // then, catch, finally
      promise //
        .then((result) => console.log(result));
        // .then(console.log)와 동일
        .catch((error) => {
          console.log(error); 
        })
        .finally(() => {
          console.log("Promise 끝!");
        });
    
  • 코드 (프로미스 2개가 then, catch, finally 처리되는 방식)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    
      const promise1 = new Promise((resovle, _) => {
        resovle("실행!");
        reject(new Error("에러!"));
      });
        
      const promise2 = new Promise((_, reject) => {
        reject(new Error("에러!"));
      });
        
      promise1 //
        .then((res) => {
          console.log(res);
        })
        .catch((err) => {
          console.log(err);
        })
        .finally(() => {
          console.log("마침내 끝!");
        });
        
      promise2 //
        .then((res) => {
          console.log(res);
        })
        .catch((err) => {
          console.log(err);
        })
        .finally(() => {
          console.log("마침내 끝!");
        });
    

    Image

  • 프로미스 체이닝
    then이 여러개 오면, 비동기 작업을 순차적으로 처리함.
    then의 결과 값 → resolve로 반환됨
    체이닝 중간에 error 발생 → 후에 오는 체이닝 중단됨!

  • 코드 (then을 여러개 사용 → 프로미스 체이닝)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    
      const promise1 = new Promise((resovle, _) => {
        setInterval(() => {
          resovle(2);
        }, 1000);
      });
        
      promise1
        .then((res) => res * 2)
        .then((res) => res * 2)
        .then(console.log)
        .catch((err) => {
          console.log(err);
        })
        .finally(() => {
          console.log("마침내 끝!");
        });
    

    Image

  • 코드 (프로미스 체이닝 중단)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    
      const promise1 = new Promise((resovle, _) => {
        setInterval(() => {
          resovle(2);
        }, 1000);
      });
        
      promise1
        .then((res) => {
          return new Promise((_, reject) => {
            reject(new Error(res * 2));
          });
        })
        .then((res) => res * 2)
        .then(console.log)
        .catch((err) => {
          console.log(err);
        })
        .finally(() => {
          console.log("마침내 끝!");
        });  
    

    Image

  • 코드 (프로미스 체이닝 중단 방지)
    에러를 중간에 잡음!

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    
      const promise1 = new Promise((resovle, _) => {
        setInterval(() => {
          resovle(2);
        }, 1000);
      });
        
      promise1 //
        .then((res) => {
          return new Promise((_, reject) => {
            reject(new Error(res * 2));
          });
        })
        .catch(() => 1)
        .then((res) => {
          return new Promise((_, reject) => {
            reject(new Error(res * 2));
          });
        })
        .catch(() => 1)
        .then(console.log)
        .catch((err) => console.log(err));
    

    Image

콜백함수 → Promise

  • 콜백지옥에 빠진 함수를 Promise 생성식으로 바꿔보자.
  • 코드
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    
      function task1() {
        return new Promise((resolve) => {
          setTimeout(() => {
            console.log("task1");
            resolve();
          }, 1000);
        });
      }
      function task2() {
        return new Promise((resolve) => {
          console.log("task2");
          resolve();
        });
      }
      function task3() {
        return new Promise((resolve) => {
          console.log("task3");
          resolve();
        });
      }
      function task4() {
        return new Promise((resolve) => {
          console.log("task4");
          resolve();
        });
      }
        
      task1() 
        .then(() => task2())
        .then(() => task3())
        .then(() => task4());
    

    Image

async 문법

  • Sugar Syntax(설탕 문법)의 예시 중 하나이다.
    • 기존 기능을 더 쉽게, 짧게 쓸 수 있게 해주는 문법
  • 기존의 형태

    1
    2
    3
    4
    5
    
      function promise() {
         return new Promise((resolve) => {
            resolve("작업 성공");
         });
      }
    
  • async 사용!
    resolve가 감싸진 Promise 객체가 리턴됨

    1
    2
    3
    
      async function promise() {
        return "작업 성공";
      }
    
    • 코드 (예시)

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      
        async function getBall1() {
          return ""; // resolve가 감싸진 Promise 객체가 리턴됨
          //   return new Promise((resolve) => {
          //     resolve("⚽");
          //   });
        }
              
        getBall1() //
          .then(console.log);
              
        async function getBall2() {
          return "";
        }
              
        getBall2() //
          .then(console.log);
              
      

async & await 문법

  • 기존의 형태

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    
      function 처리함수() {
        getHen() //
          .then((hen) => {
            getEgg() //
              .then((egg) => {
                console.log(`${hen} + ${egg} = 🍳`);
              });
          });
      }
      처리함수();
    
  • async & await 사용!
    Promise콜백 지옥에서 벗어날 수 있음

    1
    2
    3
    4
    5
    6
    
      async function 처리함수() {
        const hen = await getHen();
        const egg = await getEgg(); 
        console.log(`${hen} + ${egg} = 🍳`);
      }
      처리함수();
    
    • 코드 (예시)

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      34
      35
      36
      37
      38
      39
      
        // Sugar Syntax (설탕 문법)
        async function getHen() {
          return "🐓"; // resolve 감싸진 Promise 객체가 리턴됨
          // return new Promise((resolve) => {
          //   resolve("🐓");
          // });
        }
              
        getHen() //
          .then((hen) => console.log(hen));
              
        async function getEgg() {
          return "🥚";
        }
              
        getEgg() //
          .then((egg) => console.log(egg));
              
        // await
        function makeMeal() {
          getHen() //
            .then((hen) => {
              getEgg() //
                .then((egg) => {
                  console.log(`${hen} + ${egg} = 🍳`);
                });
            });
        }
              
        makeMeal();
              
        // await ! 기다려!
        async function makeMeal2() {
          const hen = await getHen();
          const egg = await getEgg(); //
          console.log(`${hen} + ${egg} = 🍳`);
        }
              
        makeMeal2();
      

콜백함수 → async & await

  • 콜백지옥에 빠진 함수를 async & await 형식으로 바꿔보자.
  • 코드

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    
      async function task1() {
        return new Promise((resolve) => {
          setTimeout(() => {
            console.log("task1");
            resolve();
          }, 1000);
        });
      }
      async function task2() {
        return new Promise((resolve) => {
          console.log("task2");
          resolve();
        });
      }
      async function task3() {
        return new Promise((resolve) => {
          console.log("task3");
          resolve();
        });
      }
      async function task4() {
        return new Promise((resolve) => {
          console.log("task4");
          resolve();
        });
      }
        
      async function runTask() {
        await task1();
        await task2();
        await task3();
        await task4();
      }
    

    Image


This post is licensed under CC BY 4.0 by the author.