비동기 처리(ajax)을 편하게 처리할 수 있도록 ES6 에 도입된 문법
비동기 작업의 완료 또는 실패를 나타내는 객체
👉 비동기 처리가 성공할 때에는 resolve()를 호출, 실패할 때에는 reject()를 호출하도록 설계
ES6 Promise를 이용해 작업의 순서를 명확히 정의할 수 있음
코드 구성
👩🏻💻 예시 코드
// promise 초기화 문법 const promise = new Promise((resolve, reject) => { // 비동기 처리 문장이 들어갈 곳 // ex) ajax 요청, 파싱 ... 시간이 걸리는 작업 let a = 1 + 1; if (a == 2) { // 성공했을 경우 resolve('success!!'); } else { // 실패했을 경우 reject('failed!'); } }); // promise 실행하는 코드 promise.then((msg) => { // 비동기 처리가 완료되고, 비동기 처리된 결과를 가지고 업데이트 하는 영역 // resolve가 호출되었을 때 오는 성공 패턴 document.write('결과값: ' + msg); }).catch((msg) => { // reject이나 error가 발생했을 경우 오는 영역 document.write('결과값: ' + msg); });
비동기 처리를 하기 위해선 then을 여러개를 chain으로 붙여 활용
Promise의 then은 chain으로 설계됨
👉 chain은 자기 자신(this)를 return하는 패턴
then은 then((msg)=>msg + '...')로 설계, msg는 이전 msg, return값은 다음 then으로 전달
then chain 실행 도중 에러를 발생시키면 chain이 중지
👉 then()내부에서 오류가 발생하면 가장 가까운 catch()가 호출됨
throw new Error('')를 통해 사용자 에러를 발생시켜 중지시켜도 됨
👩🏻💻 예시 코드
count = 0; element = document.getElementById('p1'); function run() { const promise2 = new Promise((resolve, reject) => { setTimeout(() => { resolve('3000ms 이후 발생하는 메시지!'); }, 3000); // 3000ms 이후 실행되는 문장 }); // 연속적인 비동기 작업을 처리하기 위해선 then chain으로 설계한다. promise2.then((msg) => { console.log(msg); element.innerHTML += 'then1, 이전 msg : ' + msg + '<br>'; return count++; // 리턴되는 값은 다음 then, msg 전달된다. }).then((msg) => { element.innerHTML += 'then2, 이전 msg : ' + msg + '<br>'; // throw new Error('에러 메시지!'); // 에러 발생시 catch로 전달됨 return count++; }).then((msg) => { element.innerHTML += 'then3, 이전 msg : ' + msg + '<br>'; return count++; // 2가 되지만 출력은 되지 않음! }).catch((error) => { element.innerHTML += 'error : ' + error + '<br>'; // 에러 발생시 해당문구 출력 }); }
👩🏻💻 예시 코드
주간/주말 박스오피스 API 서비스 링크// fetch(url, options) // .then((response) => console.log("response:", response)) // .catch((error) => console.log("error:", error)); function runFetch() { let url = document.getElementById('url').value; url += '?key=' + '4298055d882fbc5'; url += '&targetDt=' + document.getElementById('targetDt').value; console.log(url); fetch(url) .then((response) => { console.log(response); if (response.status != 200) { // 200이 아니면 error인 상황! throw new Error('Request Error!'); } return response.json(); }).then((json) => { console.log(json); const rankArray = json.boxOfficeResult.weeklyBoxOfficeList; if (rankArray == null || rankArray.length == 0) { throw new Error('json parse Error!'); } let e = document.getElementById('print'); e.innerHTML = ''; rankArray.forEach((data) => { let html = `<div> ${data.rank} - ${data.movieNm}, 일일 관객 : ${data.audiCnt}, 누적 관객 : ${data.audiAcc} </div>`; e.innerHTML += html; }); }).catch((error) => { alert(error); }); }
promise를 쉽게 활용하도록 설계된 문법
비동기 함수의 앞부분에 async를 선언하고,
promise 실행시에는 await 키워드를 붙여줌
await가 붙은 함수는 함수가 모두 실행 될때까지 block되며,
모두 실행되면 다음 문장이 실행
👩🏻💻예시 코드
function delay(ms) { return new Promise(resolve => { setTimeout(() => { alert(ms + 'ms초가 지났습니다.'); resolve(); }, ms); }); } // 기존 promise then() 구조로 여러개를 실행시켜 보기 function test1() { delay(1000).then(() => { // 성공했을 경우 resolve로 호출되는 영역 return delay(1000); }).then(() => { return Promise.resolve('끝'); }).then((msg) => { alert(msg); }); } // 동일한 기능을 가지는 async/await 설계 // async를 사용하기 위해선 함수 앞에 반드시 async가 필요! async function test2() { await delay(1000); await delay(1000); const result = await Promise.resolve('끝'); alert(result); } // 동기화 안한 함수 -> 결과가 이상하게 동작한다! 실패! function test3() { delay(1000); delay(1000); const result = Promise.resolve('끝'); alert(result); }
👩🏻💻 예시 코드
async function updateView(json) { let e = document.getElementById('print2'); const rankArray = json.boxOfficeResult.weeklyBoxOfficeList; e.innerHTML = ''; rankArray.forEach((data) => { let html = `<div> ${data.rank} - ${data.movieNm}, 일일 관객 : ${data.audiCnt}, 누적 관객 : ${data.audiAcc} </div>`; e.innerHTML += html; }) } async function runAsyncAwait() { let url = document.getElementById('url2').value; url += '?key=' + '4298055d882fbc5c120b654c1fa42815' url += '&targetDt=' + document.getElementById('targetDt2').value;
try {
const response = await fetch(url);
console.log(response);
if (response.status != 200) {
alert('request error!');
return;
}
const json = await response.json();
console.log(json);
const rankArray = json.boxOfficeResult.weeklyBoxOfficeList;
if (rankArray == null || rankArray.length == 0) {
alert('json parse error!');
return;
}
await updateView(json);
} catch (e) {
alert(e);
}
}