저번시간에 배웠던 콜백 함수!
권장하지 않는 방법이다.
요새 많은 사람들이 사용하는 Promise 에 대해서 공부해 보자!
왜 Promise가 필요한가?
ajax가 서버에다 데이터 하나만 주세요 라는 요청을 보낸다. 그런데 데이터를 받아오기도 전에 마치 데이터를
다 받아온 것 처럼 화면에 데이터를 표시하려고 하면 오류가 발생하거나 빈 화면이 뜬다.
이러한 문제점을 해결하기 위한 방법중 하나가 프로미스이다!!
간단한 예를 통해서 설명을 해보겠습니다.
function getData(callbackFunc) {
$.get('url 주소/products/1', function (response) {
callbackFunc(response); // 서버에서 받은 데이터 response를 callbackFunc() 함수에 넘겨줌
});
}
getData(function (tableData) {
console.log(tableData); // $.get()의 response 값이 tableData에 전달됨
});
위의 코드는 콜백함수를 이용한 jquery ajax 통신이다. 위의 코드를 프로미스를 적용해 보겠다.
function getData(callback) {
return new Promise(function (resolve, reject) {
$.get('url 주소', function (response) {
resolve(response); // 데이터를 받으면 resolve() 호출
});
});
}
// getData()의 실행이 끝나면 호출되는 then()
getData().then(function (tableData) {
// resolve()의 결과 값이 여기로 전달됨
console.log(tableData); // $.get()의 reponse 값이 tableData에 전달됨
});
프로미스 상태(state)는 생성하고 종료될 때까지 3가지 상태를 갖습니다.
1. pending(대기) : 비동기 처리 로직이 아직 완료 되지 않은 상태
2. Fulfilled (이행/완료 ) : 비동기 처리가 완료 되어 프로 미스가 결과 값을 반환해준 상태
3. Rejected (실패) : 비동기 처리가 실패 OR 오류가 발생한 상태
1. new Priomise() 메소드를 호출하면 대기 상태가 됩니다.
2.resolve()를 실행하면 이행/완료 상대가 되고 then()을 이용해서 처리 결과값을 받을 수 있습니다.
3.new Promise() 객체 생성을 하면 콜백 함수 인자로 resolve와 reject를 사용 할 수 있다고 했습니다.
여기서 reject 인자로 reject 메소드를 실행하면 Rejected(실패) 상태가 됩니다.
개념은 정리 되었고 그럼 내 프로젝트 코드를 Promise기법을 사용해서 refactoring 해보자
$(document).on("click", "#regist", function(){
if($('#content').val() == ''){
var toastTop = app.toast.create({
text: '댓글을 입력하세요.',
position: 'top',
closeButton: true,
});
toastTop.open();
}else{
promise_func().then(saveAlarmAjax).catch(function(err){
console.log(err);
});
}
});
간략히 설명하면 댓글 달기 버튼을 클릭했을때 내용이 유무에 따라 유효성 검사를 한다!
function promise_func(){
return new Promise(function(resolve, reject){
$.ajax({
type : 'post',
url : '/mentor/menteeboardReply/menteeboardReplyWrite',
data : $('#menteeboardViewForm').serialize(),
dataType : 'json',
success : function(data){
if(data){
$('#inputList').empty();
$('#content').val('');
$('.count').text(data.list.length);
let $frag = $(document.createDocumentFragment());
menteeboardViewList(data);
$('#inputList').append('<div class="block mentee-detail-block thanks-note-card" id="menteeboardPagingDiv">'+data.menteeboardPaging.pagingHTML+'</div><hr>');
resolve();
}else{
reject('fail');
}
}
});
});
}
여기서 봐야할부분은 data가 잘왔다면 resolve() , 데이터가 없다면 reject()를 호출한다
let memNickname = $('#memNickname').val();
let nickname = $('#nickname').val();
let receiverEmail = $('#email').val();
let menteeboard_seq = $('#menteeboard_seq').val();
var AlarmData = {
"myAlarm_receiverEmail" : receiverEmail,
"myAlarm_callerNickname" : memNickname,
"myAlarm_title" : "댓글 알림",
"myAlarm_content" : memNickname + "님이 <a type='external' href='/mentor/menteeboard/menteeboardView?seq="+menteeboard_seq+"&pg=1'>" + menteeboard_seq + "</a> 번 게시글에 댓글을 남겼습니다."
};
//댓글작성에 대한 알림 저장
function saveAlarmAjax(){
return new $.ajax({
type : 'post',
url : '/mentor/member/saveAlarm',
data : JSON.stringify(AlarmData),
contentType: "application/json; charset=utf-8",
dataType : 'text',
success : function(data){
//socket에 보내자
alert(JSON.stringify(AlarmData));
if(socket) {
let socketMsg = "reply," + memNickname +","+ nickname +","+ receiverEmail +","+ menteeboard_seq;
console.log("msgmsg : " + socketMsg);
socket.send(socketMsg);
}
}
});
}
여기에서는 댓글이 작성이 된후에 웹소켓으로 전달하는 ajax이다
결론
ajax가 꼬리에 꼬리를 물고 생기지 않아서 가독성이 좋아진 부분을 알 수 있다.
'Front-end > JavaScript' 카테고리의 다른 글
비동기 처리(Callback hell) (0) | 2019.12.17 |
---|