BlueHarmel
BlueHarmel Devlog
BlueHarmel
전체 방문자
오늘
어제

블로그 메뉴

  • 홈
  • 태그
  • 방명록
  • 분류 전체보기 (330)
    • Book (11)
    • Dev (29)
      • ArtCon (0)
      • ESTsoft 오르미 (29)
    • Study (290)
      • Web (18)
      • AWS (2)
      • 알고리즘 (1)
      • GameDev (1)
      • 정보처리기사 (201)
      • English (1)
      • Mathematics (24)
      • 머신러닝 (7)
      • 딥러닝 (10)
      • 네트워크 보안 (5)
      • R (4)
      • 컴퓨터 네트워크 (6)
      • 데이터베이스 (8)
      • 데이터 통신 (0)
      • 운영체제 (2)
      • TIL (0)
    • Project (0)
      • 개인 (0)
      • 단체 (0)

인기 글

hELLO · Designed By 정상우.
BlueHarmel

BlueHarmel Devlog

Dev/ESTsoft 오르미

JavaScript3 (DOM,AJAX)

2024. 2. 22. 09:50

1. DOM (Document Object Model)

DOM API란?

  • HTML 문서의 내용을 트리형태로 구조화하여 웹페이지와 프로그래밍 언어를 연결시켜주는 역할
  • 노드(node) : 각각의 요소와 속성, 콘텐츠를 표현하는 단위

DOM 트리에 접근하기

  • document : 브라우저가 불러온 웹페이지 / DOM 트리의 진입점
  • document 객체를 통해 HTML 문서에 접근이 가능하다.
    // 해당하는 Id를 가진 요소에 접근하기
    document.getElementById();
    
    // 해당하는 모든 요소에 접근하기
    document.getElementsByTagName();
    
    // 해당하는 클래스를 가진 모든 요소에 접근하기
    document.getElementsByClassName();
    
    // css 선택자로 단일 요소에 접근하기
    // 페이지에 있는 selector 태그중 가장 앞에 나오는 태그만 나온다
    document.querySelector("selector");
    
    // css 선택자로 여러 요소에 접근하기
    document.querySelectorAll("selector");

DOM 제어 명령어

  • 이벤트 삽입
    • target.addEventListener( type, listener )의 문법 형태를 지닌다.
    • 이벤트 MDN 설명
      <button>HELLO!</button>
      // 이벤트의 타입에는 click, mouseover, mouseout, wheel 등 다양한 이벤트를 감지합니다.
      // listener 함수의 인수에는 이벤트에 대한 정보가 담겨있습니다.
      
      const myBtn = document.querySelector("button");
      
      myBtn.addEventListener('click', function(){
      	console.log("hello world");
      })
  • 클래스 제어
    • classList 객체를 통해 요소의 class 속성을 제어할 수 있다.
      <button>Make me BLUE!</button>
      const myBtn = document.querySelector("button");
      
      myBtn.addEventListener('click', function(){
      
      // blue 라는 클래스의 속성 값을 지정 할 수 있습니다.
      	myBtn.classList.add("blue");
      
      	// myBtn.classList.remove("blue");     클래스를 제거합니다.
      	// myBtn.classList.toggle("blue");     클래스를 토글합니다. 없으면 넣어주고, 있으면 제거합니다.
      	// myBtn.classList.contains("blue");   해당하는 클래스가 있는지 확인합니다.
      })
  • JavaScript 문자열을 사용해 element, text 노드를 생성하거나 추가
    • 요소 안의 값에 접근하여 값을 가져오거나, 변경 가능
      <p></p>
      <input type="text">
      <button>Write Something!</button>
      const myBtn = document.querySelector("button");
      const myP = document.querySelector("p");
      const myInput = document.querySelector("input");
      
      myBtn.addEventListener('click', function(){
      	myP.textContent = myInput.value;
      });
      
      // input 요소에 'input' 이벤트를 연결하면 실시간으로 값이 반영되게 만들 수도 있습니다.
      myInput.addEventListener('input', ()=>{
        myP.textContent = myInput.value;
      });
      
      myP.innerHTML = "<strong>I'm Strong!!</strong>";
      
      // innerHTML 은 요소(element) 내에 포함된 HTML 마크업을 가져오거나 설정합니다. 중요한 기능은 innerHTML로 값을 할당할 때, 마크업으로 변환할 수 있는 문자열이 있다면 마크업으로 만들어 보여준다는 것 입니다. 만약 그런 문자열이 없다면 그냥 문자열만 컨텐츠로 설정합니다.
      
      // innerText 속성은 요소의 렌더링된 텍스트 콘텐츠를 나타냅니다. (렌더링된에 주목하세요. innerText는 텍스트 내에 문법적으로 처리가 가능한 텍스트가 있으면 처리가 끝난 결과물을 텍스트로 전달합니다.)
      
      // textContent 속성은 노드의 텍스트 콘텐츠를 표현합니다. 컨텐츠를 단순히 텍스트로만 다룹니다.
      💡
      innerHTML 더 생각해보기

      위의 내용을 통해 innerHTML이 의도치 않게 자바스크립트 코드를 실행시킬 수 있다는 것을 알게 되었습니다. 그럼 innerHTML은 사용해서는 안되는 속성일까요?
      그렇지 않습니다. innerHTML은 템플릿 리터럴과 조합해 복잡한 HTML 구조도 동적으로 손쉽게 생성할 수 있다는 장점이 있습니다.
      단, 자바스크립트를 작동시킬 수 있는 가능성이 있으니 나쁜 의도를 가진 사용자가 코드를 입력 할 수 없도록 사용자의 입력 값을 innerHTML을 통해 할당 받는 일만 없도록 하면 안전하게 사용할 수 있습니다. 대신 innerText 혹은 textContent 속성을 이용합시다.
      Element.innerHTML - Web API | MDN
      Element (en-US) 속성(property) innerHTML 은 요소(element) 내에 포함 된 HTML 또는 XML 마크업을 가져오거나 설정합니다.
      https://developer.mozilla.org/ko/docs/Web/API/Element/innerHTML#security_considerations
      💡
      innerText 더 생각해보기
      innerText 속성은 요소의
      렌더링된 텍스트 콘텐츠를 나타낸다고 합니다. 표현이 애매한데요, mdn 에 따르면 innerText는 사용자가 커서를 이용해 요소의 콘텐츠를 선택하고 클립보드에 복사했을 때 얻을 수 있는 텍스트의 근삿값을 제공한다고 합니다.
      이 말은 즉, 예를 들어서 네이버 메인페이지의 특정 텍스트를 복사에서 메모장에 붙여넣기한다고 가정했을때, 텍스트의 줄 바꿈같은 것은 가져오지만 폰트의 굶기나 색상까지 가져오지 않는 것과 같다고 할 수 있겠습니다.

      따라서 innerText는 display:none으로 인해 제거되는 텍스트, br 태그를 통해 줄 바꿈되는 텍스트의 '형태' 는 인식하지만 color 나 굵기, 사이즈 등 과 같은 정보는 인식하지 못한다고 볼 수 있습니다.

  • 속성 제어
    • 요소의 스타일을 제어하는 style 객체
      • 이 방식은 inline 이 되므로 다른 스타일에 악영향을 줄 수 있다.
      • 따라서 가급적 사용 X
      • 클래스(ClassList)를 통해서 적용하는 것이 가장 좋다
    • 속성에 접근하고 수정할 수 있는 Attribute 메소드
      • getAttribute : 요소의 특정 속성 값에 접근
      • setAttribute : 요소의 특정 속성 값을 수정
        <p id='myTxt'>hello lions</p>
        <img src='https://static.ebs.co.kr/images/public/lectures/2014/06/19/10/bhpImg/44deb98d-1c50-4073-9bd7-2c2c28d65f9e.jpg'>
        <script>
        	const target = document.querySelector('p');
        	const myimg = document.querySelector('img');
        	const idAttr = target.getAttribute('id');
        	console.log(idAttr);
        	myimg.setAttribute("src", "https://img.wendybook.com/image_detail/img159/159599_01.jpg");
        </script>
    • 요소에 데이터를 저장하도록 도와주는 data 속성
      • HTML 요소에 추가적인 정보를 저장하여 마치 프로그램 가능한 객체처럼 사용할 수 있게 한다.
        <img
            class="terran battle-cruiser"
            src="battle-cruiser.png"
            data-ship-id="324"
            data-weapons="laser"
            data-health="400"
            data-mana="250"
            data-skill="yamato-cannon"
        />
        <script>
            const img = document.querySelector('img')
            console.log(img.dataset);
            console.log(img.dataset.shipId);
        </script>
    • 더 인접한곳(Adjacent)으로 정밀하게 배치하기
      • insertAdjacentHTML : 요소 노드를 대상의 인접한 주변에 배치
      <strong class="sayHi">
          반갑습니다.
      </strong>
      const sayHi = document.querySelector('.sayHi');
      // 열린태그 바로 앞에 해당 요소를 추가해라
      sayHi.insertAdjacentHTML('beforebegin', '<span>안녕하세요 저는</span>');
      // 열린태그 바로 뒤에 해당 요소를 추가해라 (첫 자식)
      sayHi.insertAdjacentHTML('afterbegin', '<span>재현입니다</span>');
      // 닫는태그 바로 앞에 해당 요소를 추가해라 (마지막 자식)
      sayHi.insertAdjacentHTML('beforeend', '<span>면접오시면</span>');
      // 닫는 태그 바로 뒤에 해당 요소를 추가해라
      sayHi.insertAdjacentHTML('afterend', '<span>치킨사드릴게요</span>');
    • DOM 안에서 노드 탐색하기
      <!-- 주석입니다 주석. -->
      <article class="cont">
          <h1>안녕하세요 저는 이런 사람입니다.</h1>
          <p>지금부터 자기소개 올리겠습니다</p>
          Lorem ipsum dolor sit amet consectetur adipisicing elit. Deserunt incidunt voluptates laudantium fugit, omnis
          dolore itaque esse exercitationem quam culpa praesentium, quisquam repudiandae aut. Molestias qui quas ea iure
          officiis.
          <strong>감사합니다!</strong>
      </article>
      const cont = document.querySelector(".cont");
      console.log(cont.firstElementChild);  // 첫번째 자식을 찾습니다.
      console.log(cont.lastElementChild);   // 마지막 자식을 찾습니다.
      console.log(cont.nextElementSibling); // 다음 형제요소를 찾습니다.
      console.log(cont.previousSibling);    // 이전 형제노드를 찾습니다.
      console.log(cont.children);           // 모든 자식요소를 찾습니다.
      console.log(cont.childNodes);         // 모든 자식노드를 찾습니다.
      console.log(cont.parentElement);      // 부모 요소를 찾습니다.
      // 자기 자신부터 시작해 부모로 타고 올라가며 가장 가까운 cont 클래스 요소를 찾습니다. 단, 형제요소는 찾지 않습니다.
      console.log(cont.querySelector('strong').closest('.cont').innerHTML); 
    • 이벤트 객체
      <article class="parent">
          <ol>
              <li><button class="btn-first" type="button">버튼1</button></li>
              <li><button type="button">버튼2</button></li>
              <li><button type="button">버튼3</button></li>
          </ol>
      </article>
      const btnFirst = document.querySelector('.btn-first');
      btnFirst.addEventListener('click', (event) => {
          console.log(event);
      });
    • 이벤트 흐름
      • 캡처링 단계 : 브라우저가 이벤트 대상을 찾아갈때 window 객체부터 DOM트리를 따라 내려가는 과정
      • 버블링 단계 : 이벤트 대상을 찾고 캡처링이 끝난후, 다시 DOM 트리를 따라 올라가며 만나는 모든 버블링 이벤트 리스너를 실행
      • 이벤트 전파 : 이 과정에서 이벤트 리스너가 차례로 실행되는 것
    <!DOCTYPE html>
    <html lang="ko">
    
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Document</title>
        <link rel="stylesheet" href="../reset.css">
        <style>
        </style>
    </head>
    
    <body>
        <article class="parent">
            <button class="btn" type="button">버튼</button>
        </article>
    
        <script>
            const parent = document.querySelector('.parent');
            const btnFirst = document.querySelector('.btn');
    				//default : false
            btnFirst.addEventListener('click', (event) => {
                console.log("btn capture!");
            })
    
            window.addEventListener('click', () => {
                console.log("window capture!");
            }, true); // true : 캡처링 단계의 이벤트가 발생하도록 합니다.
    
            document.addEventListener('click', () => {
                console.log("document capture!");
            }, true);
    
            parent.addEventListener('click', () => {
                console.log("parent capture!");
            }, true);
    
            btnFirst.addEventListener('click', (event) => {
                console.log("btn bubble!");
            })
    
            parent.addEventListener('click', () => {
                console.log("parent bubble!");
            });
    
            document.addEventListener('click', () => {
                console.log("document bubble!");
            });
    
            window.addEventListener('click', () => {
                console.log("window bubble!");
            });
        </script>
    </body>
    
    </html>
    • 이벤트 target, currentTarget
      • target : 이벤트가 발생한 진원지의 정보 / 이벤트 리스너가 없는 요소의 이벤트가 발생했을때도 해당 요소에 접근 가능
      • currentTarget : 이벤트 리스너가 연결된 요소를 참조
      <article class="parent">
          <ol>
              <li><button class="btn-first" type="button">버튼1</button></li>
              <li><button type="button">버튼2</button></li>
              <li><button type="button">버튼3</button></li>
          </ol>
      </article>
      
      <script>
          const parent = document.querySelector('.parent');
          parent.addEventListener('click', function (event) {
              console.log(event.target);
              console.log(event.currentTarget);
          })
      </script>
    • 이벤트 위임 (테크닉 - 필수적인건 아님)
      <!DOCTYPE html>
      <html lang="ko">
      
      <head>
          <meta charset="UTF-8">
          <meta http-equiv="X-UA-Compatible" content="IE=edge">
          <meta name="viewport" content="width=device-width, initial-scale=1.0">
          <title>Document</title>
          <link rel="stylesheet" href="../reset.css">
          <style>
          </style>
      </head>
      
      <body>
          <article class="parent">
              <ol>
                  <li><button class="btn-first" type="button">버튼1</button></li>
                  <li><button type="button">버튼2</button></li>
                  <li><button type="button">버튼3</button></li>
              </ol>
          </article>
      
          <script>
              const parent = document.querySelector('.parent');
              parent.addEventListener('click', function (event) {
                  console.log(event.target);
                  if (event.target.nodeName === "BUTTON") {
                      event.target.textContent = "버튼4";
                  }
              })
          </script>
      </body>
      
      </html>
      • 자손 요소들에게 이벤트 리스너가 적용된것처럼 작동이 가능하다.
    • 이벤트의 this
      • 이벤트 리스너 함수 내부에서의 this는 이벤트가 연결된 노드를 참조
      • event.currentTarget과 유사
      • 이벤트 리스너 함수를 화살표 함수로 쓴다면 this가 가리키는 대상이 달라진다!
        • 화살표 함수의 this : 함수를 감싸고 있는 상위공간을 가리킨다.
        <article class="parent">
            <ol>
                <li><button class="btn-first" type="button">버튼1</button></li>
                <li><button type="button">버튼2</button></li>
                <li><button type="button">버튼3</button></li>
            </ol>
        </article>
        
        <script>
            const parent = document.querySelector('.parent');
            parent.addEventListener('click', function (event) {
                console.log(this);
            });
        
        		const myObj = {
                name: 'jaehyun',
                walk() {
                    parent.addEventListener('click', () => {
                        console.log(this.name + ' is walking');
                    })
                }
            }
        </script>
    • preventDefault()
      • 브라우저의 기본 이벤트 동작을 취소
      • 자바스크립트를 통해 기능을 처리하고자 할때 사용
      <!-- 앵커의 기본 동작을 중지 -->
      <a href="https://www.naver.com" class="link">네이버 링크입니다만..</a>
      <script>
          const link = document.querySelector('.link');
          link.addEventListener('click', (event) => {
              console.log('clicked');
              event.preventDefault();
          })
      </script>
      
      <!-- submit 의 기본 동작을 중지 -->
      <form action="">
          <button type="submit" class="submit">제출</button>
      </form>
      <script>
          const submit = document.querySelector('.submit');
          submit.addEventListener('click', (event) => {
              console.log('clicked');
              event.preventDefault();
          })
      </script>
    • stopPropagation
      • 이벤트의 전파과정을 차단
      • 부모자식 관계에 있는 요소들이 둘다 eventlistener가 달려있다면, 부모의 이벤트가 자식 이벤트에 의해 발생하는 경우를 막을 때 사용

Ajax

동기 vs 비동기

  • 동기 : 코드의 순서에 따라 코드가 처리되는 것
  • 비동기 : 코드의 순서와 별도로 동시에 코드 처리가 진행되는 것
  • 보통 언제 발생할지 모르는 일을 처리할때 비동기를 사용한다.
console.log(1);
// setTimeout으로 콜백함수가 일정시간(100ms) 뒤에 실행하도록 코드를 작성합니다. 순서대로 실행되지 않습니다.(비동기적으로 실행). 이러한 비동기 실행 코드는 setInterval, addEventListener 와 같은 함수들이 있습니다.
setTimeout(() => console.log(2), 100);
[3, 4, 5].forEach(i => console.log(i));
console.log(6);
  • setInterval() : https://developer.mozilla.org/en-US/docs/Web/API/setInterval
  • addEventListener도 비동기 방식이다
    • event가 언제 발생할지 모르기 때문에

XMLHttpRequest (XHR)

  • 서버와의 비동기 통신을 가능하게 하는 여러 기능들을 가진 자바스크립트 객체
// XHR 객체를 생성합니다.
const requestObj = new XMLHttpRequest();
requestObj.open('GET', 'url'); // 요청을 초기화합니다. 통신방법과 요청을 발신할 대상의 주소를 전달합니다.
requestObj.onreadystatechange = () => { // readystate 가 변화하면 실행되는 이벤트리스너 입니다.
		// readystate : 요청을 보내는 클라이언트의 상태를 의미합니다.
    // readystate의 종류
    // 0 (UNSENT) - XHR 객체가 생성되었지만 아직 초기화되지 않았습니다.
    // 1 (OPENED) - open()함수가 호출되어 요청이 초기화되었습니다.
    // 2 (HEADERS_RECEIVED) - send()함수가 호출되었습니다.
    // 3 (LOADING) - 데이터를 다운받는 중 입니다.
    // 4 (DONE) - 통신이 완료되었습니다.
    if (requestObj.readyState == 4 && requestObj.status == "200") {

        const result = requestObj.responseText;

    }
};
requestObj.send(); // 서버로 요청을 보냅니다. send 메소드가 실행되어야만 우리가 위에서 설정한 내용들이 의미를 가지게 됩니다.
  • callback 지옥
    • callback 함수 : 함수의 인자로 들어오는 함수
    • callback 함수가 끊이지 않는걸 의미한다.
    • 비동기 코드를 동기코드와 같이쓰는 것은 문제가 발생할 수 있다.
      • 실행 순서를 보장할 수 없기 때문에
    // sudo코드
    const result = 비동기통신함수();
    
    const result2 = 비동기통신함수2();
    
    const total = result + result2;
    
    // 이런 방식은 불가능합니다. result와 result2에 무슨 값이 들어있을지 생각해보세요.
    • 비동기 방식에서 실행 순서를 보장하기위해 callback함수를 활용할 수 밖에 없고, callback 지옥에 빠지게 된다.
    const total = 비동기통신함수( 
            input,
            통신함수의결과를가공하는함수1 ( 
                result, 
                비동기통신함수2(
                    통신함수의결과를가공하는함수2(
                        result, 
                        result2
                    )
                ) 
            ) 
        );
    
    // 이렇게 비동기 함수가 끝나기 전에 중간 중간에 필요한 콜백함수를 실행시키며 사용할 수 밖에 없었습니다.
    • 예시코드
      <script>
          'use strict';
      
          class UserStorage {
              // 사용자가 입력한 값과 유저 정보가 일치하는 유저를 찾습니다.
              searchUser(userName, password, onSuccess, onError) {
      
                  const requestObj = new XMLHttpRequest();
                  requestObj.open('GET', 'users.json'); // 요청 초기화
                  requestObj.onreadystatechange = () => {
                      if (requestObj.readyState === 4 && requestObj.status === 200) {
                          const result = JSON.parse(requestObj.responseText).user.find((item) => {
                              return item.userName === userName && item.password === password
                          });
      
                          // 사용자가 입력한 정보와 일치하는 유저가 존재한다면
                          if (result) {
                              onSuccess(userName);
                              // 사용자가 입력한 정보와 일치하는 유저가 존재하지 않는다면
                          } else {
                              onError(new Error('user not found'));
                          }
                      }
                  }
                  requestObj.send();
              }
      
              // 유저에 맞는 인사말을 출력합니다.
              sayHi(user, onSuccess, onError) {
                  const requestObj = new XMLHttpRequest();
                  requestObj.open('GET', 'greetings.json'); // 요청 초기화
                  requestObj.onreadystatechange = () => {
                      if (requestObj.readyState === 4 && requestObj.status === 200) {
                          const result = JSON.parse(requestObj.responseText).greetings.find((item) => {
                              return item.userName === user
                          });
      
                          // 사용자가 입력한 유저 이름과 일치하는 인사말이 존재한다면
                          if (result) {
                              onSuccess(result);
                              // 사용자가 입력한 유저 이름과 일치하는 인사말이 존재하지 않는다면
                          } else {
                              onError(new Error('no greetings'));
                          }
                      }
                  }
                  requestObj.send();
              }
          }
      
      
          const userStorage = new UserStorage();
      
          const userName = prompt('이름을 입력하세요.');
          const password = prompt('비밀번호를 입력하세요.');
      
          userStorage.searchUser(
              userName,
              password,
              (name) => {
                  userStorage.sayHi(
                      name,
                      (result) => {
                          alert(`당신에게 인사합니다! ${result.userName}님 ${result.greetings}`);
                      },
                      (error) => {
                          console.log(error);
                      });
              },
              (error) => {
                  console.log(error);
              }
          );
      
      </script>

    Fetch API

    • XMLHttpRequest를 대체할 새로운 API
    • XHR과의 차이점 : fetch는 인스턴스를 만들지 않고, ‘약속’을 반환한다.
    // 커피를 주문하는 프로미스 객체를 생성합니다. 생성자에는 약속을 지키기 위한 resolve와, 약속을 지키지 못했을 때를 대비한 reject 두 가지를 인자로 전달합니다. 
    // 프로미스 객체를 생성하는 순간 프로미스 생성자함수의 콜백 함수가 실행됩니다. 이를 실행자(executor)라 부릅니다.
    const orderCoffee = new Promise((resolve, reject) => {
    
      const requestObj = new XMLHttpRequest();
      requestObj.open('GET', 'orderCoffee.txt');
      requestObj.onreadystatechange = () => {
          if (requestObj.readyState === 4) {
              if (requestObj.status === 200) {
                  const result = requestObj.responseText;
                  // resolve 메소드가 실행되면 then 메소드가 자동으로 호출됩니다.
                  resolve(result);
              } else {
                  // resolve 메소드 호출이 없는 상태에서 reject 메소드가 실행되면 catch 메소드가 자동으로 호출됩니다.
                  reject(new Error(`커피주문이 정상적으로 이뤄지지 않았습니다.: ${requestObj.status}`));
              }
          }
      };
      requestObj.send();
    
    });
    
    // 이 부분에 주목해주세요. then 메소드를 사용하면 비동기 코드를 마치 동기적인 코드처럼 작성할 수 있습니다. 앞에서 작성한 XHR 코드와 비교해보는것도 좋습니다. 
    
    // resolve 메소드가 실행될때 전달된 인자는 then 메소드의 콜백함수의 인자로 전달됩니다.
    orderCoffee.then((asyncResult) => {
      console.log(asyncResult);
      console.log('약속이 이루어졌습니다.');
      return asyncResult; 
    }).catch((error) => { // then 메소드는 프라미스 객체를 반환하기 때문에 catch 메소드를 이어서 쓰는것이 가능합니다.
    // resolve 메소드와 마찬가지로 reject 메소드가 실행될때 전달된 인자는 catch 메소드의 콜백함수의 인자로 전달됩니다.
      console.log(error);
    })
    • Promise란?
      • 무언가를 할 것이라 미리 정하는 행위
      • 프로미스 객체는 약속을 지키기 위한 resolve와 약속을 지키지 못했을때를 대비한 reject 두가지를 인자로 전달한다.
      • resolve : 데이터 통신이 성공 했을때 실행
      • reject : 데이터 통신이 실패 했을때 실행
      • 서버와 통신이 성공했을때 클라이언트에서 처리해야하는 내용이 then 뒤에 나옴
      • 반대로 서버와 통신이 실패했을때 클라이언트에서 처리해야하는 내용은 catch 뒤에 나옴

async, await

  • async 키워드는 어떤 함수든 프로미스 객체를 반환하게 만들 수 있다.
  • await는 async 함수 안에서 promise 객체의 상태가 결정될 때까지 다음 코드를 대기시킨다. 그리고 프로미스 객체의 fulfilled 값을 반환한다.
  • await는 반드시 async 함수 안에서만 사용가능 하다.
async function message() {
    const hello = await new Promise((resolve) => {
        setTimeout(() => {
            resolve('hello');
        }, 100)
    })

    const world = await new Promise((resolve) => {
        setTimeout(() => {
            resolve('world');
        }, 100)
    })

    console.log(`${hello} ${world}`);
}

message();

'Dev > ESTsoft 오르미' 카테고리의 다른 글

강사님 코드리뷰  (0) 2024.02.22
공부한 기술들  (0) 2024.02.22
JavaScript2 (타입 ~)  (0) 2024.02.22
JavaScript1 (~조건문과 반복문)  (0) 2024.02.22
CSS2 (Position & Flex)  (0) 2024.02.22
    BlueHarmel
    BlueHarmel
    Interested in Mathematics, Foreign Language, and "Programming"

    티스토리툴바