Node.js 교과서 - 알아두어야 할 자바스크립트

윤재·2021년 10월 7일
0

호출 스택

function first() {
  second();
  console.log('첫 번째');
}
function second() {
  third();
  console.log('두 번째');
}
function third() {
  console.log('세 번째');
}

first();

// 세 번째 -> 두 번째 -> 첫 번째

쉽게 파악이 안된다면 호출스택을 머리속으로 그려보자

호출 스택(함수의 호출, 자료구조의 스택)

  • Anonymous는 가상의 전역 컨텍스트(항상 있다고 생각하는게 좋음, 실행이 모두 끝나면 사라짐)
  • 함수 호출 순서대로 쌓이고, 역순으로 실행됨
  • 함수 실행이 완료되면 스택에서 빠짐
  • LIFO 구조라서 스택이라고 불림

이벤트 루프

function run() {
  console.log('3초 후 실행');
}
console.log('시작');
setTimeout(run, 3000);
console.log('끝');

// 시작 -> 끝 -> 3초 후 실행

비동기 함수 setTimeout(run, 3000)은 호출되면 백그라운드에 쌓인다.
호출스택에 다음 코드인 console.log('끝') 이 불려서 실행되는 와중에도 백그라운드에서 3초를 세며 자신의 동작인 run을 대기한다. ( 호출스택과 백그라운드가 동시에 작동된다.)
3초가 지나면 백그라운드에 남아있는 동작 run이 태스크 큐로 이동한다. 호출 스택에 모든게 끝나서 텅텅 비어있다면(annonymous 포함) run을 호츨스택에 올려 console.log('3초 후 실행')이 동작한다.

(Promise의 then/catch setTimeout보다 더 먼저 작동함(새치기))


화살표 함수

let relationship1 = {
  name: 'zero',
  friends: ['nero', 'hero', 'xero'],
  logFriends: function () {
    let that = this; // relationship1을 가리키는 this를 that에 저장
    this.friends.forEach(function (friend) {
      console.log(that.name, friend);
    });
  },
};
relationship1.logFriends();
// zero nero
// zero hero
// zero xero

화살표 함수가 기존 function() {}을 대체하는건 아님(this가 달라짐)

  • logFriends 메소드의 this값에 주목
  • forEach의 function의 this와 logFriends의 this는 다름
  • that이라는 중간변수를 이용해서 logFriends의 this를 전달

.

let relationship2 = {
  name: 'zero',
  friends: ['nero', 'hero', 'xero'],
  logFriends() {
    this.friends.forEach(friend => {
      console.log(this.name, friend);
    });
  },
};
relationship2.logFriends();

forEach의 인자로 화살표 함수가 들어간 것에 주목

  • forEach의 화살표함수의 this와 logFriends의 this가 같아짐
  • 화살표 함수는 자신을 포함하는 함수의 this를 물려받음
  • 물려받고 싶지 않을 때 function() {}을 사용

즉 !!

this를 쓸거면 기존함수, this를 쓰지 않아도 되면 화살표함수 사용을 권장한다. (오해 방지)


클래스

프로토타입 문법을 깔끔하게 작성할 수 있는 Class 문법 도입

  • Constructor(생성자), Extends(상속) 등을 깔끔하게 처리할 수 있음
  • 코드가 그룹화되어 가독성이 향상됨

Promise

콜백 헬이라고 불리는 지저분한 자바스크립트 코드의 해결책

  • 프로미스? 내용이 실행은 되었지만 결과를 아직 반환하지 않은 객체

  • Then을 붙이면 결과를 반환함

  • 실행이 완료되지 않았으면 완료된 후에 Then 내부 함수가 실행됨

  • Resolve(성공리턴값) -> then으로 연결

  • Reject(실패리턴값) -> catch로 연결

  • Finally 부분은 무조건 실행됨

const condition = true; // true면 resolve, false면 reject
const promise = new Promise((resolve, reject) => {
  if (condition) {
    resolve('성공');
  } else {
    reject('실패');
  }
});
// 다른 코드가 들어갈 수 있음
promise
  .then((message) => {
	console.log(message); // 성공한 경우 실행(resolve)
})
  .catch((error) => {
	console.error(error); // 실패한 경우 실행(reject)
})

Promise.all(배열): 여러개의 프로미스를 동시에 실행

  • 하나라도 실패하면 catch로 감
  • allSettled로 실패한 것만 추려낼 수 있음

async/await

  • 변수 = await 프로미스; 인 경우 프로미스가 resolve된 값이 변수에 저장
  • 변수 await 값; 인 경우 그 값이 변수에 저장
async function findAndSaveUser(Users) {
  let user = await Users.findOne({});
  user.name = 'zero';
  user = awajit user.save();
  user = await Users.findOne({ gender: 'm' });
// 생략
}
profile
안 되면 될 때까지

0개의 댓글