HomeAboutMeBlogGuest
© 2025 Sejin Cha. All rights reserved.
Built with Next.js, deployed on Vercel
💌
JJong’s Archive
/
🌞
JS
/
promise

promise

Status
Done
Tags
비동기
API
날짜
Oct 16, 2023 06:22 AM

Promise

ex)
let myFirstPromise = new Promise((resolve, reject) => { // 하단의 비동기 작업이 성공한 경우 resolve(...)를 호출하고, 실패한 경우 reject(...)를 호출 // 여기서는 setTimeout()을 사용해 비동기 코드를 흉내, 실제로는 여기서 XHR이나 HTML5 API를 사용 setTimeout(function () { resolve("성공!"); // 와! 문제 없음! }, 250); }); myFirstPromise.then((successMessage) => { // successMessage : 위에서 resolve(...) 호출에 제공한 값 console.log("와! " + successMessage); });
  • 비동기 작업이 맞이할 미래의 완료 또는 실패와 그 결과 값을 나타냄
  • 비동기 메서드에서 마치 동기 메서드처럼 값을 반환
    • 최종 결과x, 미래의 결과에 대한 약속을 반환
    • callback hell에서 어느정도 해방 가능
      • chaining 방식(.then().then()…)으로 1depth
      •  
  • 상태
    • 대기(pending): 이행하지도, 거부하지도 않은 초기 상태.
    • 이행(fulfilled): 연산이 성공적으로 완료됨.
    • 거부(rejected): 연산이 실패함.
  • 이행이나 거부될 때, 프로미스의 then 메서드에 의해 대기열(큐)에 추가된 handler들이 호출됨
 
  • 생성 : new Promise(executor)
    • executor : (resolve, reject) ⇒ {} 형태
      • 프로미스를 지원하지 않는 함수를 감쌀 때 사용
      • 실행 함수의 반환값은 무시됨
    • 어떤 비동기 작업을 시작한 후
      • 모든 작업을 성공적으로 끝내면 인자에 반환 값을 넣은 resolve를 호출해 프로미스를 이행
      • 오류가 발생한 경우 인자에 반환 값을 넣은 reject 를 호출해 거부
 

정적 메서드

  • resolve(value) : 주어진 값으로 이행하는 Promise 를 반환
    • 어떤 값이 프로미스인지 아닌지 알 수 없는 경우, 보통 일일히 두 경우를 나눠서 처리하는 대신 Promise.resolve()로 값을 감싸서 항상 프로미스가 되도록 만든 후 작업하는 것이 좋다.
    • ex)
      const cahced = { 'roto' : 'bassist' } const findMember = (memberName) => { //항상 프로미스를 반환 if (chached[memberName]) { return Promise.resolve(chached[memberName]) //프로미스로 만듦 } return request('http~') .then((member)=> { cache[memberName] = member.job return member.job //해당 프로미스의 결과값을 이걸로 변경 } } findMember('roto').then((job) => console.log(job))
  • reject(reason) : 주어진 사유로 거부하는 Promise 를 반환
    • 강제로 reject해야할 때 사용
  • all(프로미스배열) : 배열 안에 있는 모든 프로미스가 다 resolve되거나, 한 프로미스가 reject될 때까지 대기하는 새로운 프로미스를 반환
    • 모두 reolve된다면, 각 resolve 값 순서대로 모두 모아놓은 배열이 then handler의 매개변수로 제공
    • 한개라도 reject되면 첫 reject된 프로미스 사유가 catch handler의 매개변수로 제공
  • allSettled(프로미스배열) : 모든 프로미스가 resolve/reject 됐을 경우 프로미스를 반환
    • 각 결과(resolve 값이나 reject 사유)를 순서대로 모두 모아놓은 배열이 then handler의 매개변수로 제공
  • race(프로미스배열) : 모든 프로미스 중 첫번째로 resolve/reject된 프로미스를 반환
  • any(프로미스배열) : 모든 프로미스 중 첫번째로 resolve된 프로미스를 반환
 

인스턴스 메서드

  • then : resolve의 handler를 추가
    • handler의 매개변수는 promise의 이행 결과값이다
    • 반환 값이 있다면, 해당 promise의 결과 값이 이 반환 값으로 변경된다.
    • 호출되지 않는 경우, 상태에 맞는 값과 콜백을 가진 새로운 프로미스를 반환
  • catch : reject의 handler 추가
    • 호출되지 않는 경우(resolve된 경우), resolve 값과 콜백을 가진 새로운 프로미스를 반환
    • 넣지 않을 경우 promise chain이 멈추므로 가급적으로 넣는 것이 좋음
  • finally : 여부에 상관없이 처리될 경우 항상 호출되는 처리기 콜백
    • 새로운 프로미스를 반환
 
  • .then으로 비동기 함수들을 chaining할 수 있음
    • ex)
      const delay = (delayTime) => new Promise((resolve) => { setTimeout(resolve, delayTime) }) delay(5000) .then(() => { return delay(3000) }).then(() => { console.log('complete') });
 
 
 

 
<api.js를 promise로 바꿔보기>
전) App.js에서 콜백함수 → api.js로 넘겨서 그 함수에 data를 인자로 넣어 사용
후) api.js에서 data를 resolve의 결과 값 → App.js로 넘겨서 data 사용
  • api.js : resolve/reject 알려줌
  • App.js : then, catch 처리
 
api.js
  • 이제 콜백함수를 넘겨받지 않음.
export function request(url) { return new Promise((resolve, reject) => { const xhr = new XMLHttpRequest(); xhr.addEventListener("load", (e) => { if (xhr.readyState === 4) { if (xhr.status === 200) { resolve(JSON.parse(xhr.responseText)); } else { reject(xhr.statusText); } } }) xhr.addEventListener('error', (e) => reject(xhr.statusText)) xhr.open('GET', url) xhr.send() }) }
 
App.js
  • then으로 resolve handler를 추가
  • 콜백함수의 매개변수인 data는 promise의 이행 결과값이다
//댓글 목록 불러오기 request(`https://kdt-frontend.programmers.co.kr/comments?todo.id=${id}`) .then((data) => { this.setState({ ...this.state, comments: data }) }); ... //todos 불러오기 this.init = () => { request("https://kdt-frontend.programmers.co.kr/todos") .then((data) => { this.setState({ ...this.state, todos : data }) }) }