(비동기 처리를 할 때 응답이 올 때까지 기다리는 JavaScript 객체이다.)
1) 대기상태 : pending, 이행도 하지 않고 거부도 하지 않은 초기 상태
2) 이행상태 : fulfilled, 비동기 처리가 성공적으로 완료된 상태
3) 거부상태 : reject, 비동기 처리가 실패된 상태
1) Promise.resolve() : 이행상태에서 호출하는 메소드이다. resolve() 메소드가 반환하는 프로미스는 then() 메소드를 따라가서 처리된다.
2) Promise.reject() : 거부상태에서 호출하는 메소드이다. reject() 메소드가 반환하는 프로미스는 catch() 메소드를 따라가서 처리된다.
var promise = new Promise(function(resolve, reject){
// 랜덤으로 이행상태(성공)와 거부상태(실패)를 생성
if(Math.random() < 0.5){
resolve('이행'); // resolve() 메소드를 호출하면 then() 메소드에서 정의한 함수가 실행된다.
} else {
reject('거부'); // reject() 메소드를 호출하면 catch() 메소드에서 정의한 함수가 실행된다.
}
});
promise.then(function(str){
console.log(str + '상태');
})
promise.catch(function(str){
console.log(str + '상태');
})
new Promise(function(resolve, reject){
$.ajax({
type: 'get',
url: 'product1.xml',
async: true,
dataType: 'xml',
success: function(resData){
resolve($(resData).find('product').length); // resolve(3)
},
error: function(jqXHR){
reject(jqXHR.status); // reject(404)
}
})
}).then(function(length){
console.log(length);
}).catch(function(status){
console.log(status);
})
[12_Promise.html]
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="../../assets/js/lib/jquery-3.7.1.min.js"></script>
</head>
<body>
<script>
// 비동기 통신은 요청 이후에 응답을 기다리지 않는다!
var a; // a는 undefined
$.ajax({
type: 'get',
url: 'product1.xml',
async: true,
dataType: 'xml',
success: function(resData){
a = $(resData).find('product').length;
}
})
console.log(a); // a는 3을 기대하지만, ajax 응답이 올 때까지 기다리지 않고 이 코드가 처리된다.
</script>
<script>
/*
Promise 객체
1. 비동기 처리의 결과(성공 또는 실패) 값을 나타낼 수 있는 객체이다.
(비동기 처리를 할 때 응답이 올 때까지 기다리는 JavaScript 객체이다.)
2. Promise 상태
1) 대기상태 : pending, 이행도 하지 않고 거부도 하지 않은 초기 상태
2) 이행상태 : fulfilled, 비동기 처리가 성공적으로 완료된 상태
3) 거부상태 : reject, 비동기 처리가 실패된 상태
3. Promise 메소드
1) Promise.resolve() : 이행상태에서 호출하는 메소드이다. resolve() 메소드가 반환하는 프로미스는 then() 메소드를 따라가서 처리된다.
2) Promise.reject() : 거부상태에서 호출하는 메소드이다. reject() 메소드가 반환하는 프로미스는 catch() 메소드를 따라가서 처리된다.
*/
// Promise 객체 생성
var promise = new Promise(function(resolve, reject){
// 랜덤으로 이행상태(성공)와 거부상태(실패)를 생성
if(Math.random() < 0.5){
resolve('이행'); // resolve() 메소드를 호출하면 then() 메소드에서 정의한 함수가 실행된다.
} else {
reject('거부'); // reject() 메소드를 호출하면 catch() 메소드에서 정의한 함수가 실행된다.
}
});
// Promise가 이행상태인 경우
promise.then(function(str){
console.log(str + '상태');
})
// Promise가 거부상태인 경우
promise.catch(function(str){
console.log(str + '상태');
})
</script>
<script>
// Promise 객체 생성 + then() 메소드 호출 + catch() 메소드 호출
new Promise(function(resolve, reject){
$.ajax({
type: 'get',
url: 'product1.xml',
async: true,
dataType: 'xml',
success: function(resData){
resolve($(resData).find('product').length); // resolve(3)
},
error: function(jqXHR){
reject(jqXHR.status); // reject(404)
}
})
}).then(function(length){
console.log(length);
}).catch(function(status){
console.log(status);
})
</script>
<hr>
<!-- Promise 예시. ajax이 ajax을 호출하는 동작 시나리오 -->
<script>
/*
동작 시나리오
1. ajax1 : 입력한 이메일이 사용 가능한 이메일인지 확인한다. (DB에 등록된 이메일인지 여부 확인)
2. ajax2 : 사용 가능한 이메일이라면 인증 메일을 보낸다.
*/
function checkEmail(){
return new Promise(function(resolve, reject){
// 사용자의 이메일
var email = 'admin@web.com';
// 1. ajax1 : 입력한 이메일이 사용 가능한 이메일인지 확인한다. (DB에 등록된 이메일인지 여부 확인)
$.ajax({
type: 'get',
url: 'validEmail.json', // {"validEmail": true} 또는 {"validEmail": false}
async: true,
data: 'email=' + email, // 사용자의 이메일을 서버로 보냄
dataType: 'json',
success: function(resData){
if(resData.vaildEmail){
resolve(email);
} else {
reject(email);
}
}
})
})
}
checkEmail().then(function(email){
// 사용자가 입력한 인증코드
var authcode = '654321';
// 2. ajax2 : 사용 가능한 이메일이라면 인증 메일을 보낸다.
$.ajax({
type: 'get',
url: 'authentication.json', // {"authcode": "123456"} (의미: 사용자의 이메일로 보낸 인증코드)
async: true,
data: 'email=' + email,
success: function(resData){
if(authcode === resData.authcode){
alert('인증되었습니다.');
} else {
alert('인증실패했습니다.');
}
}
})
}).catch(function(email){
alert(email + ' 이메일은 이미 등록되었습니다.');
})
</script>
<hr>
<!-- Promise 예시. 이미지 표시하기 -->
<div>
<button id="btn">이미지열기</button>
<div id="img"></div>
</div>
<script>
$('#btn').click(function(){
var no = parseInt(Math.random() * 10 + 1); // 1 ~ 10 사이의 랜덤 값 생성
openImage('../../assets/image/animal' + no + '.jpg');
})
function openImage(imageURL){
new Promise(function(resolve, reject){
// ajax을 이용해서 이미지를 blob(Binary Type, 이진타입) 타입으로 가져오기
$.ajax({
type: 'get',
url: imageURL,
async: true,
xhrFields: {
responseType: 'blob'
},
success: function(resData){ // resData에는 이미지의 이진 데이터가 전달됨
resolve(resData);
},
error: function(jqXHR){
reject(jqXHR);
}
})
}).then(function(resData){
var img = new Image(); // <img> 태그를 만드는 JavaScript 객체
img.src = URL.createObjectURL(resData); // 이미지의 이진 데이터를 <img> 태그로 만든 뒤 가상 주소를 src 속성에 넘긴다.
$('#img').empty();
$('#img').append(img);
}).catch(function(jqXHR){
alert(jqXHR.status + '(' + jqXHR.statusText + ')');
})
}
</script>
</body>
</html>
[authentication.json]
{
"authcode":"123456"
}
[validEmail.json]
{
"validEmail":true
}
