callback을 사용하면 비동기 로직의 결과값을 처리하기 위해서는 callback 안에서만 처리를 해야하고, callback 밖에서는 비동기에서 온 값을 알 수가 없다.
반면에 promise를 사용하면 비동기에서 온 값이 promise 객체에 저장되기 때문에 코드작성이 용이해진다.
function async(callback) {
var result;
setTimeout(() => {
result = callback("결과값");
},1000);
return result;
}
var b = async((res) => {
return res;
})
만약 async 함수에서 비동기가 끝난 후의 값을 가지고 싶어서 위처럼 코드를 썼다면, b를 1초 후, 100초 후에 찍어도 undefined만 나오게 된다.
var p = new Promise((res, rej) => {
setTimeout(() => {
res("a")
}, 1000)
})
var result = p.then(res => {
return res;
})
console.log(result) // Promise {<fulfilled>: "a"}
result.then(res => {
console.log(res); // "a"
})
프로미스를 사용하게 되면 프로미스 객체에 비동기가 처리된 결과값이 저장된다. 콜백의 경우 매번 비동기를 실행해야지 그 값을 사용(?)할 수 있지만 프로미스는 .then 메소드를 통해서 저장되어 있는 값을 원하는 때에 사용할 수 있다.
function async(result, callback) {
setTimeout(() => {
callback(result, function (result) {
console.log(result);
});
}, 1000);
}
async(0, function (res, callback) {
callback(res)
async(res + 1, function (res, callback) {
callback(res)
async(res + 1, function (res, callback) {
callback(res)
});
});
});
// 0
// 1
// 2
위처럼 비동기 로직의 결과를 다음 비동기로 전달해서 실행해야 할 때 callback은 점점 깊어져서 가독성이 매우 안좋아지고, 코드를 작성할 때도 힘들어진다.
function async(result) {
return new Promise((resolve, reject) => {
setTimeout(() => {
console.log(result);
resolve(result);
}, 1000)
});
}
async(0).then(res => {
return async(res + 1);
}).then(res => {
return async(res + 1);
})
// 0
// 1
// 2
프로미스를 사용할 경우 .then을 통해 코드의 깊이가 깊어지지 않고, 이해하기도 쉽다.
일반적으로 웹 애플리케이션을 구현할 때 서버에서 데이터를 요청하고 받아오기 위해 API를 사용하는데,
API가 실행되면 서버에다가 데이터 보내달라는 요청을 보내고,
여기서 데이터를 받아오기도 전에 마치 데이터를 다 받아온 것 마냥 화면에 데이터를 표시하려고 하면 오류가 발생하거나 빈 화면이 뜬다.
이같은 문제를 해결하기 위해 프로미스를 사용한다.
프로미스는 pending, fullfilled, rejected 3가지 상태(states)가 존재하며,
이행을 할 때 resolve()를 실행하면 이행상태가 된다.
이행 상태가 되면 then을 이용하여 처리 결과 값을 받을 수 있고
실패는 reject()로 실행하여 실패 상태가 된다.
출처 :
https://jcon.tistory.com/189
https://velog.io/@southbig89/1%EC%9B%94-27%EC%9D%BC-%EC%88%98-promise-%EC%99%80-callback-http%EC%99%80-https-%EC%9D%98-%EC%B0%A8%EC%9D%B4