본문 바로가기
웹 프로그래밍

[JS] Promise 이해하기

by Minius 2020. 6. 28.
반응형

Promise를 공부하기전에 동기/비동기? 한번 더 짚고가기

동기(synchronous): 함수들이 차례대로 실행되는 것

비동기(asynchronous): 비동기함수가 아닌 것들이 실행되고 난 뒤, 비동기함수가 실행된다.

예)

console.log(1);
setTimeout(() => {
	console.log(2);
},0)
console.log(3);
console.log(4);
console.log(5);
console.log(6);

// 1
// 3
// 4
// 5
// 6
// 2

실행 화면

이처럼 setTimeout의 시간이 0초후에 이루어진다. 바로 이루어진다고 해도 비동기함수기 때문에 다른 함수들이 실행되고 난 뒤에 실행된다.

 

Promise도 비동기 함수이다.


Promise에는 3가지 상태가 있다.

  • 대기(pending): 이행하거나 거부되지 않은 초기 상태.
  • 이행(fulfilled): 연산이 성공적으로 완료됨.
  • 거부(rejected): 연산이 실패함.

from. MDN

1. pending에서 시작하여 fullfill과 reject 둘 중 하나의 상태로 넘어간다.

2. then으로 fullfill과 reject의 과정을 거쳐 action을 하거나, error handling을 한다.

3. 결과값을 return한다.

 

callback 함수를 더 정확하고 예쁘게 표현하기 위해 쓰는 함수인 것 같다.

또한 콜백지옥이라는 곳에 갇히지 않기 위해.

 

기본 예제

let myFirstPromise = new Promise((resolve, reject) => {  
  setTimeout(function(){
    resolve("Success!"); // Yay! Everything went well!
  }, 250);
});

myFirstPromise.then((successMessage) => {
  console.log("Yay! " + successMessage);
});

myFirstPromise에 Promise 함수를 설정하고, 실행을 할 때

요청이 성공했을 시, 요청값이 return 될 때 then메소드로 원하는 action을 실행한다.

따라서 여기서는 250ms 후에 "Yay! Success!"가 나온다.

 

고급 예제

'use strict';
var promiseCount = 0;

function testPromise() {
    var thisPromiseCount = ++promiseCount;

    var log = document.getElementById('log');
    log.insertAdjacentHTML('beforeend', thisPromiseCount +
        ') 시작 (<small>동기적 코드 시작</small>)<br/>');

    // 새 프로미스 생성 - 프로미스의 생성 순서를 전달하겠다는 약속을 함 (3초 기다린 후)
    var p1 = new Promise(
        // 실행 함수는 프로미스를 이행(resolve)하거나
        // 거부(reject)할 수 있음
        function(resolve, reject) {
            log.insertAdjacentHTML('beforeend', thisPromiseCount +
                ') 프로미스 시작 (<small>비동기적 코드 시작</small>)<br/>');
            // setTimeout은 비동기적 코드를 만드는 예제에 불과
            window.setTimeout(
                function() {
                    // 프로미스 이행 !
                    resolve(thisPromiseCount);
                }, Math.random() * 2000 + 1000
            );
        }
    );

    // 프로미스를 이행했을 때 할 일은 then() 호출로 정의하고,
    // 거부됐을 때 할 일은 catch() 호출로 정의
    p1.then(
        // 이행 값 기록
        function(val) {
            log.insertAdjacentHTML('beforeend', val +
                ') 프로미스 이행 (<small>비동기적 코드 종료</small>)<br/>');
        })
    .catch(
        // 거부 이유 기록
        function(reason) {
            console.log('여기서 거부된 프로미스(' + reason + ')를 처리하세요.');
        });

    log.insertAdjacentHTML('beforeend', thisPromiseCount +
        ') 프로미스 생성 (<small>동기적 코드 종료</small>)<br/>');
}

 

마찬가지로 p1에 promise 함수를 설정하고

안에 function(resolve, reject)를 넣어준다.

성공시 resolve, 실패시 reject를 한다.

성공지 then 메소드로 값을 처리하고, 실패시 catch 메소드로 에러를 처리한다.

 

내가 내린 결론

let promiseSomething = new Promise(resolve, reject){
	// 요청사항...
    // ajax 등 api 요청
    resolve("받은 값");
}

promiseSomething.then(function(val){
	// 성공시 할 action
    console.log("받은 값은 " + val + "입니다.");
    // 받은 값은 받은 값입니다.
}).catch(function(){
	// 실패시 할 action
});

 


이외 정보들

  • Promise 함수는 IE에서는 작동하지 않는다.
  • IE에서 작동시키기 위해서는 BLUEBIRD.JS라는 라이브러리를 사용하면 된다.

http://bluebirdjs.com/docs/getting-started.html

 

Getting Started | bluebird

This article is partially or completely unfinished. You are welcome to create pull requests to help completing this article. Node.js Then: var Promise = require("bluebird"); Alternatively in ES6 import * as Promise from "bluebird"; If that ES6 import doesn

bluebirdjs.com

 

댓글