상세 컨텐츠

본문 제목

[javascript] Promise와 async/await

Web/Javascript

by 클리엘 클리엘 2021. 2. 26. 17:22

본문

728x90

Promise는 어떠한 처리를 하되 당장 결과를 반환하지 않고 원할 때 결과를 갸져 올 수 있는 객체입니다.

var promise = new Promise((resolve, reject) => {
    if (true) {
        resolve('true');
    }
    else {
        reject('false');
    }
});

//다른코드

promise.then((result) => {
    console.log(result);
})
.catch((result) => {
    console.log(result);
});

Promise를 위와 같이 정의해 두면 Promise 내부 코드는 즉시 실행됩니다. 그런 후 필요에 따라 다른 처리를 하고 이후에 then이나 catch를 붙여서 처리결과를 가져오는 형태인데 비동기 처리와 유사합니다.

 

만약 처리결과가 성공이면 resolve() 함수를 호출해 필요한 값을 전달하고 나중에 then() 함수를 호출하여 resolve() 함수에서 전달된 값을 받아 올 수 있습니다. 또는 처리결과가 실패이면 reject() 함수를 호출하고 이후 catch() 함수의 호출을 통해 결과값을 받으면 됩니다.

 

만약 처리결과가 성공이든 실패든 어떠한 동작이 무조건 실행되어야 하면 finally 함수를 사용할 수 있습니다.

promise.then((result) => {
    console.log(result);
})
.catch((result) => {
    console.log(result);
})
.finally(() => {
    console.log('반드시 실행');
});

필요하다면 Promise는 then안에서 또 다른 처리를 수행하여 다음 then으로 넘기는 체이닝을 구현하는 것도 가능합니다.

promise.then((result) => {
    console.log(result);

    return new Promise((resolve, reject) => {
        resolve(result);
    });
})
.then((result) => {
    console.log(result);
})
.catch((result) => {
    console.log(result);
})
.finally(() => {
    console.log('반드시 실행');
});

then안에서 또 다른 Promise를 구현해 이를 다음 then으로 넘기고 있습니다. 따라서 다음 then에서는 이전 then안에 있는 Promise의 Resolve() 메서드로 전달된 값을 받게 됩니다.

 

이때 Promise의 처리결과가 실패인지, 성공인지에 대한 결과가 명확하다면 Promise에서 resolve()나 reject() 메서드를 곧바로 호출해 결과를 받는것도 가능합니다.

var promise = Promise.resolve('true');

promise.then((result) => {
    console.log(result);
});

경우에 따라서 Promise를 여러개 사용할 수도 있는데

var promise1 = new Promise((resolve, reject) => {
    if (true) {
        resolve('true');
    }
    else {
        reject('false');
    }
});

var promise2 = new Promise((resolve, reject) => {
    if (true) {
        resolve('true');
    }
    else {
        reject('false');
    }
});

이때는 all이나 allSettled를 사용해 지정한 모든 Promise의 결과를 한꺼번에 받아올 수 있습니다.

Promise.all([promise1, promise2])
.then((result) => {
    console.log(result);
});

allSettled는 기존의 성공, 실패 결과에서 status라는 상태가 추가돼 status로부터 성공한 것, 혹은 실패한 것에 대한 Promise결과만 걸러낼 수 있습니다.

 

async/await는 Promise구현 문법을 좀더 간략하게 만들어 코드를 깔끔하게 유지시킬 수 있도록 도와줍니다. async/await의 기본적인 구현 방법은 다음과 같습니다.

var myCar = {
    car_name     : '승용차',
    car_color    : '파란색',
    car_speed    : 0,
    accelerate    : function() {
        return this.car_speed + 10;
    }
};


async function DoSomthing(myCar) {
    var result = await myCar.accelerate();

    console.log(result);
};

DoSomthing(myCar);

DoSomthing() 함수는 async 자체가 Promise에 해당하며 await를 통해 결과를 받게 됩니다. async함수는 항상 Promise를 반환한다는 점을 기억하면 이해하기 쉽습니다. 이런 부분 때문에 async 함수안에서 어떠한 값을 return 하는 경우 return의 결과는 다음과 같이 받을 수 있습니다.

async function DoSomthing(myCar) {
    var result = await myCar.accelerate();

    console.log(result);

    return 1;
};

DoSomthing(myCar).then((v) => {
    var rtn = v;

    console.log(rtn);
});

한 가지 주의해야 할 점은 async/await를 사용할 경우 reject를 처리하는 부분이 없기 때문에 오류를 대비해 try ~ catch문으로 묶어주는 과정이 필요합니다.

async function DoSomthing(myCar) {
    try {
        var result = await myCar.accelerate();
        console.log(result);

        return 1;
    }
    catch {
        //
    }
};

async/await의 또 다른 활용방안은 all을 사용해 Promise의 결과를 한꺼번에 받아오는 경우 다음과 같이 for문으로 결과값을 순회할 수 있습니다.

(async() => {
    for await (p of [promise1, promise2]) {
        console.log(p);
    }
})();

 

728x90

관련글 더보기

댓글 영역