비동기 Call하면 "그냥 Jquery의 ajax로 다 바르면 되잖아! 근데 자꾸 무슨 Promise냐..." 이렇게 생각하곤했다.
하지만 기술의 발전을 따라 가지 못하면 도태됨으로 Promise를 배웠다.(빠른건 아니지만..) 적용해보니 확실히 코드도 깔끔해지고 좋은것 같다. javascript의 싱글스레드를 좀 더 이해 하는 느낌도 들면서, 고수가 된 느낌도 들면서
정의 : Promise 개체는 비동기 작업이 맞이할 미래의 완료 또는 실패와 그 결과 값을 나타냅니다.
내 생각: 비동기 Call을 날리고 성공(resolve)과 실패(reject)를 내가 깔끔하게 처리해줄게(Callback 쓰지마세요) 왜냐? 코드가 더러워지니깐 이게 다 깔끔하려고 하는거다
코드를보자
1. 첫번째 간단한 Promise 예제
// 정의
let p = new Promise((resolve, reject) => {
let a = 1 + 1;
if (a === 2) {
resolve('Success')
} else {
reject('False')
}
});
// 실행
p.then((data => {
console.log('resolve' + data) // 성공 시 Success
})).catch((data => {
console.log('reject' + data) // 실패 시 False
}));
간단하게 말해서 Call 날린뒤 성공은 then의 함수가 실패하면 catch의 함수가 실행된다.(이때 함수는 Arrow function을 사용했다) a는 2니깐 당연히 then 함수의 Success가 실행됨!
2-1. 두번째 Promise 적용 전
const bossLeft = true;
const workLeft = false;
function goToHome(callback, errorCallback) {
if (bossLeft) {
errorCallback('아 집에좀 가세요')
} else if(workLeft) {
errorCallback('아 일좀 줄여주세요 진짜')
} else {
callback('상사도 없고 일도 없으니 집간다')
}
}
goToHome((message) => {
console.log(message)
}, (message) => {
console.log(message)
});
goToHome 집에 가는 함수다. 파라미터로 callback과 errorCallback을 받아서 상사가 남아있냐, 일이 남아있냐에 따라서 실행될 함수가 결정된다.
2-2. 두번째 Promise 적용 후
const bossLeft = false;
const workLeft = false;
function goToHome() {
return new Promise((resolve, reject) =>{
if (bossLeft) {
reject('아 집에좀 가세요')
} else if(workLeft) {
reject('아 일좀 줄여주세요 진짜')
} else {
resolve('상사도 없고 일도 없으니 집간다')
}
});
}
goToHome().then((message)=>{
console.log(message);
}).then(()=>{ // 이런식으로 then을 더붙이면 then 실행 후 그 다음 또 실행함
console.log('그다음 콜백?');
}).catch((message)=>{
console.log(message)
});
이렇게 코드가 깔끔해진다! goToHome은 파라미터를 받을 필요도 없어지고 new Promise의 reslove, reject로 결정하면된다. 추가로 resolve 호출은 then, 실패는 catch다. 더 추가로 then뒤에 다시 then을 붙이면 또 실행된다. 꿀이다.
3. 세번째 Promise all
let firstPromise = new Promise((resolve, reject)=>{
resolve('first complete')
});
let secondPromise = new Promise((resolve, reject)=>{
resolve('second complete')
});
let thirdPromise = new Promise((resolve, reject)=>{
resolve('third complete')
});
Promise.all([firstPromise, secondPromise, thirdPromise]).then((message)=>{
console.log(message)
});
3개의 Promise 모두 비동기 Call이 모두 끝났을때 then의 함수를 실행시킨다. 이거 진짜 물건이다. 비동기 Call을 하나로 묶어주는 역할!
4. 네번째 Ajax와 Promise의 만남
getOnetoFiveRanking = () => {
return new Promise((resolve, reject)=>{
$.ajax({
url: this.url1,
crossDomain: true,
data:JSON.stringify(this.form.serialize()),
dataType: 'json',
contentType: "application/json",
headers:{"x-api-key": "비밀"},
type: 'POST',
}).done((data)=>{
resolve(data); // done 시 resolve
}).fail(function (xhr, textStatus) {
reject(xhr, textStatus); // ,fail 시 reject
});
})
};
this.getOnetoFiveRanking().then((data)=>{
console.log(data);
}).catch((xhr, textStatus)=>{
console.log(xhr, textStatus);
});
$.ajax의 done일때 resolve, fail일때 reject! 심플하고 좋다.
5. 다섯번째 Ajax와 Promise.all()의 만남
getOnetoFiveRanking = () => {
return new Promise((resolve, reject)=>{
$.ajax({
url: this.url1,
crossDomain: true,
data:JSON.stringify(this.form.serialize()),
dataType: 'json',
contentType: "application/json",
headers:{"x-api-key": "비밀"},
type: 'POST',
}).done((data)=>{
resolve(data);
}).fail(function (xhr, textStatus) {
reject(xhr, textStatus);
});
})
};
getSixtoTenRanking = () => {
return new Promise((resolve, reject)=>{
$.ajax({
url: this.url2,
crossDomain: true,
data:JSON.stringify(this.form.serialize()),
dataType: 'json',
contentType: "application/json",
headers:{"x-api-key": "비밀2"},
type: 'POST',
}).done((data)=>{
resolve(data);
}).fail(function (xhr, textStatus) {
reject(xhr, textStatus);
});
})
};
// getOnetoFiveRanking와 getSixtoTenRanking 비동기 Call이 둘다 끝나면 then 실행!
Promise.all([this.getOnetoFiveRanking(), this.getSixtoTenRanking()]).then((message)=>{
console.log(message);
});
여기서 주의할 점은 메소드를 실행하듯()을 붙여야 한다는것! 그러면 두 메소드가 다 실행되면 그때 then을 수행한다! 이건 정말 실전에서 많이 쓰이니깐 유용함
결론 : callback을 깔끔하게 쓰기위해 Promise를 쓰자