Javascript/비동기 처리

Promise 나온이유 및 사용방법(feat. 만약 callback함수를 쓰게 된다면?, Promise의 문제점)

appmaster 2021. 2. 2. 15:03

ES6 버전에서 나왔고 비동기작업을 쉽게 처리할 수 있도록 도와주는 역할을 합니다.

이전에는 비동기작업이 끝나면 실행하라고 callback함수를 이용했었습니다.

callback함수로 처리하게 된다면 비동기 작업이 많아질 경우 코드가 매우 복잡해지게 되었습니다.

 

그래서 promise가 나왔습니다. 원래는 라이브러리로 존재했었습니다. 그런데, 이제는 매우 편하다 보니 아애 자바스크립트 스팩에 추가 되었습니다.

 

 

1. Promise 사용방법 (resolve, then) 성공했을때

const myPromise = new Promise((resolve, reject)=>{
    setTimeout(()=>{
        resolve('hello');
    }, 1000)
});

myPromise.then(result=>{
    console.log(result);
})
//출력값
hello

Promise를 1초동안 작성되게 만들고, Promise가 끝난후에 작동하는것은 then으로 합니다.

그리고 then은 resolve에 들어있는값을 받아오는 역할을 합니다.

 

 

 

2. Promise 애러가 있을때 사용방법 (reject, catch) 실패했을때

const myPromise = new Promise((resolve, reject)=>{
    setTimeout(()=>{
        reject(new Error());
    }, 1000)
});

myPromise.then(result=>{
    console.log(result);
}).catch(e=>{
    console.error(e);
})
//출력값
Error
    at Timeout._onTimeout (c:\Users\~~~~~)
    at listOnTimeout (internal/timers.js:554:17)
    at processTimers (internal/timers.js:497:7)

1초동안 작성되게 만들고, Promise가 끝난후에 작동하는것은 catch로 합니다.

그리고 catch는 reject에 들어있는값을 받아오는 역할을 합니다.

 

 

 

3. resolve와 reject를 함께 쓰기 (feat. then을 연달아 쓰기)

function increaseAndPrint(n){
    return new Promise((resolve, reject)=>{
        setTimeout(()=>{
            const value = n+1;
            if(value === 5){
                const error = new Error();
                error.name = 'ValueIsFiveError';
                reject(error);
                return;
            }
            console.log(value);
            resolve(value);
        }, 1000);
    });
}


increaseAndPrint(1).then(n=>{
    return increaseAndPrint(n);
}).then(n=>{
    return increaseAndPrint(n);
}).then(n=>{
    return increaseAndPrint(n);
}).catch(e=>{
    console.error(e);
})
//출력값
2
3
4
Error [ValueIsFiveError]

 

 

 

4. then을 더 간단하게 사용하기

function increaseAndPrint(n){
    return new Promise((resolve, reject)=>{
        setTimeout(()=>{
            const value = n+1;
            if(value === 5){
                const error = new Error();
                error.name = 'ValueIsFiveError';
                reject(error);
                return;
            }
            console.log(value);
            resolve(value);
        }, 1000);
    });
}


increaseAndPrint(1).then(increaseAndPrint)
.then(increaseAndPrint)
.then(increaseAndPrint)
.then(increaseAndPrint)
.catch(e=>{
    console.error(e);
})

 

 

 

이렇게해서 promise는 복잡한 동기과정을 코딩을해도 직관적으로 볼 수 있고 코딩의 깊이가 깊어지지않기때문에 편합니다.

 

 

하지만 문제점이 있습니다.

만약 애러를 잡을때, 어떤부분에서 애러가 발생한건지 파악하기가 어렵습니다. 그리고 특정 조건에따라서 분기를 나누는것도 어렵습니다. then으로 결과가 이루어지기때문에, 만약 2번째나 3번째 then에서 오류가 나지않아도 다른걸로 출력하게 함수를 만든다던지, 하는 작업이 어려워집니다. 그리고 특정 값을 공유해서 새로운 작업하기도 어려운점이 있습니다. 

 

그래서 async/await이 나오게 된겁니다.