스터디 포스트 >  웹 개발 실전 프로젝트

Javascript 뿌시기 2-1

조재홍 멘토
이로운 개발자가 되고 싶은 조재홍입니다.

웹 개발 실전 프로젝트 - 2주차

 
💡
DOM, AJAX, API 등을 배우고 터미널 기초를 배워보자
 

241. DOM 개요

  • DOM은 문서 객체 모델(Document Object Model)
  • 웹 페이지를 구성하는 JavaScript 객체들의 집합
 

242. 문서 오브젝트

  • 브라우저가 웹 페이지를 띄울 때 HTML과 CSS 정보를 받아들인 다음 요소와 스타일을 기반으로 JavaScript 객체를 생성한다.
  • 트리 구조 최상위 객체는 document
  • console.dir(document)
  • document.all
 

243. getElementById

  • 요소 선택을 도와주는 메서드
  • 메서드에 문자열을 전달하면 일치하는 id를 가진 요소를 찾아 선택하고, 없으면 null로 나타난다.
  • HTML이 아닌 JavaScript 객체로 구조화된 DOM의 객체를 찾는다.
notion image
 

244. getElementsByTagName & ClassName

  • 둘은 유사한 성질에, 배열 같은 객체인 HTML 집합을 반환한다.
  • HTMLCollection은 배열이 아니므로 배열 메서드를 사용할 수 없다.
    • 이터러블 객체라서 length나 인덱스, for ... of문은 활용할 수 있다.
notion image
없으면 빈 배열같은 빈 집합이 나타난다.
없으면 빈 배열같은 빈 집합이 나타난다.
 

245. querySelector & querySelectorAll

  • querySelector는 첫 번째로 일치하는 요소를 반환한다.
    • notion image
  • querySelectorAll은 일치하는 모든 요소를 반환한다.
const doneTodos = document.querySelectorAll('.done');
const checkbox = document.querySelector(`input[type="checkbox"]`);
코딩 연습 52: querySelector Practice
 

246. innerHTML, textContent & innerText

  • DOM Manipulation(조작)
    • JavaScript로 HTML/CSS의 중간에 엑세스를 해서 항목 이동, 이름 재지정, 스타일 업데이트, 항목 나타내고 숨기기 등 영향을 주는 것
 
  • innerText 는 여는 태그와 닫는 태그 사이에 있는 내용(텍스트)
    • const allLinks = document.querySelectorAll('a');
      
      for (let link of allLinks) {
      	link.innerText = 'I AM A LINK!!!'
      }
      notion image
  • innerTexttextContent
    • textContent는 element 안의 텍스트가 그대로 나온다. (줄바꿈까지)
    • innerText는 현재 보이는 내용에 따라 달라진다. (display: none; 시 마크업에 있더라도 보이지 않기 때문에 출력 X)
 
💡
innerHTML 은 여는 태그와 닫는 태그 사이에 있는 요소 내부의 태그를 포함한 모든 콘텐츠를 반환한다. 유일하게 element를 다른 element 안에 추가할 때 사용할 수 있다.
💡
innerText내부의 텍스트를 반환하므로 태그는 모두 무시하고 현재 표시된 내용에 따라 달라지게 되며, 숨겨진 항목은 무시된다.
💡
textContent 는 innerText와 비슷하지만, 현재 나타난 내용이나 사용자에게 보이는 내용은 신경쓰지 않는다.

247. 속성(Attributes)

attribute에 접근하거나 교체하기

  • attribute에 접근하는 방법은 메서드 방식이나 직접 엑세스하는 방식으로 나뉜다.
    • 다소 차이가 있다.
notion image
  • getAttribute 메서드로 attribute에 접근할 경우
    • HTML 자체에서 직접 가져오는 방식
  • setAttribue 로 속성 값을 교체할 수 있다.
    • firstLink.setAttribute('href', 'https://www.google.co.kr/');
  • 메서드가 아니라 직접 접근(엑세스)할 경우 .href
    • (HTML을 파싱해서 생성된) JavaScript 객체를 거쳐서 나온다.
  • 직접 엑세스해서 속성 값을 교체할 수도 있다.
notion image
const picture = document.querySelector('img');
picture.src = 'https://devsprouthosting.com/images/chicken.jpg';
// 직접 엑세스
picture.setAttribute('alt', 'chicken');
// 메서드 방식
코딩 연습 54: Manipulating Attributes Practice
 

248. 스타일 변경하기

notion image
  • 각각의 CSS 프로퍼티에 해당하는 특성들이 모두 케밥 케이스가 아닌 카멜 케이스임을 볼 수 있다.
notion image
  • querySelectorAll을 사용한 예시
    • const allLinks = document.querySelectorAll('a');
      for (let link of allLinks) {
          link.style.color = 'rgb(0, 108, 134)';
      		link.style.textDecorationColor = 'margenta';
      		link.style.textDecorationStyle = 'wavy';
      }
  • JavaScript를 사용해 인라인 스타일을 사용할 수 있지만 선호되는 방식은 아니다.
    • 마크업 안에 스타일이 생겼기 때문에 권장 X
    • 또한 애초에 스타일을 인라인으로 쓰지 않는 한 그 스타일을 읽어들일 수 없다.

window.getComputedStyle()

  • 모든 스타일이 다 적용되고 나면 실제로 계산된 스타일을 가져오는 방법
  • JavaScript의 관점에서 단순히 스타일 시트의 값을 가져오는 것이 아니라, 모든 항목이 로드된 후 브라우저에 의해 최종 계산된 값을 가져온다.
  • CSSStyleDeclaration 객체. 순서도 존재함
notion image
  • 찾고자 하는 프로퍼티가 인라인 스타일로 적혀있지 않아도 읽어들일 수 있다.
notion image
  • 문자열이 나오기 때문에 변경할 때 parseInt 처리를 하는 등 작업을 하면 된다.
 
const container = document.getElementById('container');
container.style.textAlign = 'center';

const image = document.querySelector('img');
image.style.width = '150px';
image.style.borderRadius = '50%';
코딩 연습 55: Magical Forest Circle Exercise
const colors = ['red', 'orange', 'yellow', 'green', 'blue', 'indigo', 'violet']; //PLEASE DON'T CHANGE THIS LINE!

//YOU CODE GOES HERE:
const spans = document.querySelectorAll('span');
for (let i = 0; i < spans.length; i++) {
    spans[i].style.color = colors[i];
}
코딩 연습 56: Rainbow Text Exercise
 

249. classList

  • style 특성으로 인라인 스타일을 지정하는 방법은 많은 스타일을 한번에 설정하는 경우 좋은 방법이 아니다.
  • 실제로는 JavaScript로 클래스를 다루는 경우가 더 많다.
  • getAttributesetAttribute 로 클래스를 조작할 경우
notion image
  • 여러 개의 클래스를 다룰 때는 위처럼 하지 말고 classList 를 쓰면 편하다!
    • 요소의 클래스를 제어, 검색, 조작하기 위해 호출하는 객체
    • 이미 있는 클래스를 신경쓰지 않아도 된다. add 로 추가 remove 로 제거
      • notion image
    • contains 로 특정 클래스의 유무를 확인
      • notion image
    • toggle 특정 스타일이 토글되는 인터페이스에서 유용하게 쓰인다.
      • notion image
 
const liElems = document.querySelectorAll('li');
for (let li of liElems) {
    li.classList.toggle('highlight');
}
코딩 연습 57: ClassList Practice
 

250. 계층 이동

  • 주어진 시작점에서 트리 구조와 계층 구조를 따라 이동하는 방법
  • 해당 요소 제거, 삽입 및 해당 요소의 부모 요소나 자식 요소를 변경하는 데 유용하다.
  • parentElement 부모 요소는 하나만 존재
    • notion image
  • children 자식 요소는 여러 개가 될 수 있다. (단일 특성 X)
    • notion image
    • children 은 배열처럼 생긴 HTMLCollection을 반환한다.
    • 배열 메서드는 없지만 인덱스가 있어서 반복 가능(iterable)
  • nextElementSibling, previousElementSibling 형제 요소는 한 요소에서 인접한 요소로 이동
    • nextSibling, previousSibling 은 노드를 반환한다.
      • notion image
 

251. append & appendChild

createElement

  • 새 요소를 처음부터 만드는 법

appendChild

  • appendChild 를 사용해 body의 마지막 자식으로 추가하기
    • notion image
      notion image

apppend

  • 어떤 항목을 요소의 마지막 자식으로 삽입시킨다.
    • appendChild 보다 최신 메서드, 더 유연한 기능
    • 한번에 한 개 이상을 삽입하거나, 문자열도 전달할 수 있다.
append 로 한번에 여러 요소 추가하기
append 로 한번에 여러 요소 추가하기
appendChild 로는 문자열을 전달할 수 없다.
appendChild 로는 문자열을 전달할 수 없다.

prepend

  • 어떤 항목을 요소의 첫 번째 자식으로 삽입시킨다.

insertAdjacentElement

  • position을 지정해줘야 한다.
    • beforebegin - 특정 요소의 앞 (인접)
    • afterbegin - 요소 내 첫 번째 자식 앞
    • beforeend - 요소 내 마지막 자식 뒤
    • afterend - 특정 요소의 뒤 (인접)
    • notion image
  • after before 메서드도 있다.
 
const container = document.getElementById('container');
for (let i = 0; i < 100; i++) {
    const button = document.createElement('button');
    button.textContent = 'Hey!';
    container.appendChild(button);
}
코딩 연습 58: 100 Button Insanity Exercise
 

252. removeChild & remove

removeChild

  • 제거하려는 요소의 부모를 선택해 메서드를 호출해야 한다.
const img = document.querySelector('img');
img.parentElement.removeChild(img);

remove

  • 제거하려는 요소에 호출하는 메서드
const img = document.querySelector('img');
img.remove();
 

253. 포켓몬 게임 데모

// https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/1.png

const container = document.querySelector('#container');
const baseURL = 'https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/'


for (let i = 1; i <= 151; i++) {
    const pokemon = document.createElement('div');
    pokemon.classList.add('pokemon');
    const label = document.createElement('span');
    label.innerText = `#${i}`;
    const newImg = document.createElement('img');
    newImg.src = `${baseURL}${i}.png`


    pokemon.appendChild(newImg);
    pokemon.appendChild(label);
    container.appendChild(pokemon)
}
.pokemon {
    display: inline-block;
    text-align: center;
}
.pokemon img {
    display: block;
}

255. 이벤트 개요

  • 이벤트 인터랙티브 앱을 만들기 위해 사용자의 행동에 반응하는 방법
 

256. 인라인 이벤트

<body>
	<button onclick="alert('you clicked me!')">Click Me!</button>
  <button ondblclick="alert('you double clicked me!')">Double Click Me!</button>
</body>
notion image
  • [[FunctionLocation]] 이 index.html에 있는 것을 볼 수 있다.
 

257. 온클릭(onClick) 속성

const btn = document.querySelector('#v2');

btn.onclick = function () {
	console.log('YOU CLICKED ME!');
}

function scream() {
	console.log('AAAAHHHHHHHH');
}

btn.onmouseenter = scream;
  • 함수를 직접 호출하지 않고 onclick 이나 onmouseenter 로 전달하는 것
  • 이벤트가 일어날 때 함수가 호출되어 실행된다.
 

258. addEventListener

  • 첫 번째 인수로 이벤트의 종류, 두 번째 인수로 콜백 함수를 전달
const btn3 = document.querySelector('#v3');
btn3.addEventListener('click', () => {
	alert('CLICKED!');
});
  • 왜 많이 쓰일까?
    • onclick 등 특성(프로퍼티) 메서드로는 동일한 이벤트에 대해 두 개의 서로 다른 콜백 함수를 지정할 수 없다.
      • button.onclick = twist; // ❌ 적용 안됨
        button.onclick = shout; // ⭕ shout만 적용됨
    • addEventListener로는 가능하다.
      • button.addEventListener('click', twist); // ⭕
        button.addEventListener('click', shout); // ⭕
    • 다른 옵션 객체를 전달할 수도 있다.
      • button.addEventListener('click', twist, { once: true });
        이 콜백은 해당 이벤트가 발생할 때 처음 한번 실행된 뒤 제거됨
 
const helloBtn = document.querySelector('button#hello');
const byeBtn = document.querySelector('button#goodbye');

helloBtn.addEventListener('click', () => {
    console.log('hello');
})

byeBtn.addEventListener('click', () => {
    console.log('goodbye');
})
코딩 연습 60: Click Events Exercise
 

259. 랜덤 컬러 연습하기

const button = document.querySelector('button');
const h1 = document.querySelector('h1');

button.addEventListener('click', function () {
    const newColor = makeRandColor();
    document.body.style.backgroundColor = newColor;
    h1.innerText = newColor;
})

const makeRandColor = () => {
    const r = Math.floor(Math.random() * 255);
    const g = Math.floor(Math.random() * 255);
    const b = Math.floor(Math.random() * 255);
    return `rgb(${r}, ${g}, ${b})`;
}
 

260. 이벤트와 ‘this’라는 키워드

  • 이벤트가 어디에서 일어나든 키워드 this 는 그 요소를 참조한다.
    • this는 execution context나 invocation context에 좌우된다.
const makeRandColor = () => {
    const r = Math.floor(Math.random() * 255);
    const g = Math.floor(Math.random() * 255);
    const b = Math.floor(Math.random() * 255);
    return `rgb(${r}, ${g}, ${b})`;
}

const buttons = document.querySelectorAll('button');
for (let button of buttons) {
    button.addEventListener('click', colorize)
}

const h1s = document.querySelectorAll('h1');
for (let h1 of h1s) {
    h1.addEventListener('click', colorize)
}

function colorize() {
    this.style.backgroundColor = makeRandColor();
    this.style.color = makeRandColor();
}
 

261. 키보드 이벤트와 이벤트 객체

이벤트 객체

  • 이벤트 객체는 콜백 함수에 자동으로 전달된다. 매개변수를 넣어 수집할 수 있다.
    • 소위 e, event, evt 등으로 쓴다.

키보드 이벤트

  • key: a, (공백), Shift
  • code: KeyA, Space, ShiftLeft (키보드에서의 실제 위치)
window.addEventListener('keydown', function (e) {
    switch (e.code) {
        case 'ArrowUp':
            console.log("UP!");
            break;
        case 'ArrowDown':
            console.log("DOWN!");
            break;
        case 'ArrowLeft':
            console.log("LEFT!");
            break;
        case 'ArrowRight':
            console.log("RIGHT!");
            break
        default:
            console.log("IGNORED!")
    }
})
 

262. 폼 이벤트(Form Events)와 preventDefault

  • preventDefault이벤트 객체에 사용하면 기본 동작을 방지한다.
  • 예를 들어, 폼 이벤트의 기본 동작은 action에 http 요청을 보내 데이터를 전송하고 새로고침하는 것이지만, preventDefault를 사용하면 요청이 발생하지 않는다.
  • 기본 동작을 방지한 후, input에 입력된 데이터를 추출해서 페이지에 추가하는 등 폼의 내용을 처리할 수 있다.
  • 각 input에 name을 부여하면 엑세스하기 쉽다.
<body>
	<form action="/dogs" id="tweetForm">
	    <input type="text" name="username" placeholder="username">
	    <input type="text" name="tweet" placeholder="tweet">
	    <button>Post Tweet</button>
	</form>
	
	<h2>Tweets:</h2>
	<ul id="tweets">
	
	</ul>
</body>
const tweetForm = document.querySelector('form#tweetForm');
const tweetsContainer = document.querySelector('ul#tweets');

tweetForm.addEventListener('submit', function (e) {
    e.preventDefault();
		const usernameInput = tweetForm.elements.username;
    const tweetInput = tweetForm.elements.tweet;
		addTweet(usernameInput.value, tweetInput.value)
    usernameInput.value = '';
    tweetInput.value = '';
});

const addTweet = (username, tweet) => {
    const newTweet = document.createElement('li');
    const bTag = document.createElement('b');
    bTag.append(username)
    newTweet.append(bTag);
    newTweet.append(`- ${tweet}`)
    tweetsContainer.append(newTweet);
}
 
// Leave the next line, the form must be assigned to a variable named 'form' in order for the exercise test to pass
const form = document.querySelector('form');
const lists = document.querySelector('ul#list');

form.addEventListener('submit', (e) => {
    e.preventDefault();
    const productInput = form.elements.product;
    const quantityInput = form.elements.qty;
    addList(quantityInput.value, productInput.value);
    quantityInput.value = ''; // 입력값 초기화
    productInput.value = ''; // 입력값 초기화
})

const addList = (quantity, product) => {
    const li = document.createElement('li');
    li.textContent = `${quantity} ${product}`;
    lists.appendChild(li);
}
코딩 연습 61: Form Events Exercise
 

263. 입력과 변경 이벤트

  • keydown, keyup 등은 input에 입력할 때 화살표 키, shift 키 등도 인식하고, 마우스 오른쪽 클릭으로 붙여넣기 하는 값은 포함하지 못한다.
  • change는 input에 모든 값을 입력한 후 포커스가 blur될 때 발생한다.
 
  • 💡 타이핑할 때마다 이벤트를 발생시키려면 input 이벤트를 사용하면 된다.
    • 타이핑하는 글자나 글자 수를 실시간으로 반영시키거나, 블로그 포스트를 작성할 때 쓰는 실시간 미리보기 등은 모두 input 이벤트를 사용한 것이다.
    • const input = document.querySelector('input');
      const h1 = document.querySelector('h1');
      
      input.addEventListener('input', function (e) {
          h1.innerText = input.value;
      })
 
const h1 = document.querySelector('h1');
const usernameInput = document.querySelector('#username');

usernameInput.addEventListener('input', (e) => {
    const username = e.target.value;
    if (!username) {
        h1.textContent = 'Enter Your Username';
    } else {
        h1.textContent = `Welcome, ${username}`;
    }
})
코딩 연습 62: Input Event Practice
 

264. 이벤트 버블링

  • 특정 요소에서 이벤트가 발동되면 브라우저가 그 이벤트를 부모 요소들을 타고 최상위에 있는 화면 요소까지 전파시키는 것
    • 버튼을 클릭하면 버튼 클릭 시 이벤트리스너만 동작하는 것이 아니라, 부모 요소인 컨테이너의 이벤트리스너도 동작한다.
  • 이를 막으려면 이벤트 객체의 stopPropagation 메서드를 사용해서 이벤트가 더이상 버블링하지 않도록 막을 수 있다.
const container = document.querySelector('#container');
const button = document.querySelector('#changeColor');

container.addEventListener('click', function () {
    container.classList.toggle('hide');
})
button.addEventListener('click', function (e) {
    container.style.backgroundColor = makeRandColor();
    e.stopPropagation();
})

const makeRandColor = () => {
    const r = Math.floor(Math.random() * 255);
    const g = Math.floor(Math.random() * 255);
    const b = Math.floor(Math.random() * 255);
    return `rgb(${r}, ${g}, ${b})`;
}
<div id="container">
    Click To Hide
    <button id="changeColor">Change Color</button>
</div>
 

265. 이벤트 위임(delegation)

  • 상위(부모) 요소에 이벤트 핸들러를 추가하고, 이벤트 객체의 target 특성을 이용하면 클릭한 요소를 확인할 수 있다.
  • 이벤트 핸들러를 추가한 시점에 페이지에 없었던 요소를 다루어야 하는 상황에서 편리하다.
tweetsContainer.addEventListener('click', function (e) {
    e.target.nodeName === 'LI' && e.target.remove();
})

270. 섹션 주제

  • WebAPIs는 알면 좋다. 반드시 숙달해야 할 것은 아니다.
  • 콜백과 콜백 지옥은 important
  • Promises로 작업하기와 비동기 함수는 crucial !!
 

271. 콜 스택 (Call Stack)

  • JavaScript 인터프리터가 사용하는 메커니즘으로, 함수 호출(Function call)을 관리하는 방법
  • 여러 함수를 호출하는 스크립트에서 해당 위치를 추적한다.
  • 스택(Stack)은 컴퓨터 과학의 기본 데이터 구조
    • 후입선출(LIFO)
  • 스크립트가 함수를 호출하면 인터프리터가 콜스택에 추가 → 그 함수를 수행하기 시작함 → 첫 번째 함수가 호출한 다른 함수도 콜스택에 추가되어 호출되면 실행됨 → 현재 함수가 완료되면 인터프리터는 콜스택에서 함수를 제거 → 마지막 코드 목록의 멈춘 곳에서부터 계속 실행
const multiply = (x, y) => x * y;

const square = (x) => multiply(x, x);

const isRightTriangle = (a, b, c) => {
	return square(a) + square(b) === square(c);
};

isRightTriangle(3, 4, 5);
  • 크롬 디버거 사용하기 (개발자 도구 Sources 탭)
    • 중단점(breakpoint) 넣기
    • JavaScript가 코드, 함수 호출에서 위치를 찾도록 도와주는 구조화 도구
 

272. WebAPI와 단일 스레드

  • JavaScript는 단일 스레드(Single Thread)이다.
    • 멀티태스킹을 할 수 없고, 한번에 최대 한 줄의 코드만 실행한다.
  • 브라우저의 Web APIs는 일반적으로 JavaScript에서 호출하여 브라우저로 전달하는 방법이다.
    • background에서 특정 작업을 처리할 수 있게 해준다. (요청(requests)이나 setTimeout과 같은 Web API 함수들)
    • 브라우저는 대개 C++ 같은 언어로 작성되기 때문에 JavaScript가 못하는 일을 한다.
  • JavaScript의 콜스택이 Web API 함수를 인식해서 브라우저에 전달한다.
  • 브라우저가 작업을 마치게 되면 콜스택에 다시 추가하고 JavaScript는 이어받아 다시 적절한 코드를 실행한다.
  • Web API 함수와 콜백 함수 → 2가지 메커니즘으로 작동한다.
 

273. Callback이라는 지옥 :(

비효율적인 방식들
setTimeout(() => {
	document.body.style.backgroundColor = 'red';
}, 1000)

setTimeout(() => {
	document.body.style.backgroundColor = 'orange';
}, 2000)

setTimeout(() => {
	document.body.style.backgroundColor = 'yellow';
}, 3000)
위 코드를 아래 코드처럼 중첩하게 되는 형태
setTimeout(() => {
	document.body.style.backgroundColor = 'red';
	setTimeout(() => {
		document.body.style.backgroundColor = 'orange';
		setTimeout(() => {
			document.body.style.backgroundColor = 'yellow';
		}, 1000)
	}, 1000)
}, 1000)
const delayedColorChange = (newColor, delay, doNext) => {
	setTimeout(() => {
		document.body.style.backgroundColor = newColor;
		doNext && doNext();
	}, delay)
}

delayedColorChange('red', 1000, () => {
		delayedColorChange('orange', 1000, () => {
			delayedColorChange('yellow', 1000, () => {
			})
		})
	})
}
  • 시간을 모를 경우
searchMoviesAPI('amadeus', () => {
	saveToByDB(movies, () => {
		//if it works, run this:
	}, () => {
		//if it doesn't work, run this:
	})
}, () => {
	//if API is down, or request failed
})
함수에 전달하는 두 개의 콜백이 있는 패턴 (성공 / 실패)
 

274. 데모: Callback을 사용한 fakeRequest

  • promise 는 어떤 비동기 연산이 최종적으로 성공했는지 실패했는지를 알려주는 객체
  • 자주 경험하게 될 케이스는 요청을 보내 다른 위치에서 데이터를 받는 것
    • Nexflix API, Amazon API, Goodreads API, 날씨 API, ...
  • 실패의 원인은 다양하다.
    • 시간이 오래 걸리거나, 접속이 안되거나, 접근 권한이 없거나, URL을 잘못 썼거나, API나 인터넷이 다운되었거나, ...
콜백지옥 예시
const fakeRequestCallback = (url, success, failure) => {
	const delay = Math.floor(Math.random() * 4500) + 500;
	setTimeout(() => {
		if (delay > 4000) {
			failure('Connection Timeout :(');
		} else {
			success(`Here is your fake data from ${url}`);
		}
	}, delay)
}

fakeRequestCallback('books.com/page1',
	function (response) {
		console.log('IT WORKED!!!');
		console.log(response);
		fakeRequestCallback('books.com/page2',
			function (response) {
				console.log('IT WORKED AGAIN!!!');
				console.log(response);
						fakeRequestCallback('books.com/page3',
							function (response) {
								console.log('IT WORKED AGAIN (3rd req)!!!');
								console.log(response);
							},
							function (err) {
								console.log('ERROR (3rd req)!!!', err);
							})
			},
			function (err) {
				console.log('ERROR (2nd req)!!!', err);
			})
	},
	function (err) {
		console.log('ERROR!!!', err);
	})
  • promise는 비동기 코드를 얻음과 동시에 중첩 콜백 지옥에 빠지지 않게 해준다.
 

275. 데모: Promise를 사용한 fakeRequest

const fakeRequestPromise = (url) => {
	return new Promise((resolve, reject) => {
		const delay = Math.floor(Math.random() * (4500)) + 500;
		setTimeout(() => {
			if (delay > 4000) {
				reject('Connection Timeout :(')
			} else {
				resolve(`Here is your fake data from ${url}`)
			}
		}, delay)
	})
}
  • pending은 기다리는 상태
  • resolve와 reject는 성공과 실패를 뜻한다.
  • 함수 안에 콜백을 전달하는 게 아니라, Promise 객체 자체에 콜백을 첨부해야 한다.
const request = fakeRequestPromise('yelp.com/api/coffee');
request.then(() => {
	console.log('IT WORKED!!');
});
  • then 을 쓰고 또 콜백을 전달한다. 그러면 promise가 resolved 되었을 때 콜백이 실행된다.
notion image
notion image
  • 이렇게 rejected 되었을 때도 콜백을 실행할 수 있는데, 그때는 catch 를 사용한다.
const request = fakeRequestPromise('yelp.com/api/coffee');
request
	.then(() => {
		console.log('PROMISE RESOLVED!');
	})
	.catch(() => {
		console.log('PROMISE REJECTED!!!');
	});
notion image
💡
Promise 객체의 메서드로 then 에는 성공(resolved) 시, catch 에는 실패(rejected) 시 실행할 콜백을 전달한다.
 
  • 연쇄를 하려면 then 메서드 안에 다시 promise를 중첩시키면 된다.
fakeRequestPromise('yelp.com/api/coffee/page1')
	.then(() => {
		console.log('PROMISE RESOLVED!');
		fakeRequestPromise('yelp.com/api/coffee/page2')
			.then(() => {
				console.log('PROMISE RESOLVED (2)!');
			})
			.catch(() => {
				console.log('PROMISE REJECTED (2)!!!');
			});
	})
	.catch(() => {
		console.log('PROMISE REJECTED!!!');
	});
notion image
 

 
 
 
본 스터디는 Udemy의 <【한글자막】 The Web Developer 부트캠프 2022> 강의를 활용해 진행됐습니다. 강의에 대한 자세한 정보는 아래에서 확인하실 수 있습니다.
 
 
프밍 스터디는 Udemy Korea와 함께 합니다.
 
원하는 스터디가 없다면? 다른 스터디 개설 신청하기
누군가 아직 원하는 스터디를 개설하지 않았나요? 여러분이 직접 개설 신청 해 주세요!
이 포스트는
"웹 개발 실전 프로젝트" 스터디의 진행 결과입니다
진행중인 스터디
웹 개발 실전 프로젝트
JavaScript를 이용한 DOM 조작으로 프론트엔드 분야를 배우고, Node JS와 Express, DB, HTTP, REST API 등 백앤드 지식을 학습할수 있습니다. 이론만 공부하는 스터디가 아니라 13개 이상의 프로젝트로 이루어진 실습 위주의 커리큘럼으로 개인 프로젝트 결과물을 가져갈 수 있다는 메리트가 있습니다.
조재홍 멘토
이로운 개발자가 되고 싶은 조재홍입니다.