# async, await 테스트
async 함수와 await 설정 확인 하기.
해당 예제 코드는 모던 스크립트의 async await test code를 참조했습니다.
async- async/await: Javascript Info
function 앞에 async 키워드를 추가하면 두 가지 효과가 있습니다.
1. 함수는 언제나 프라미스를 반환합니다.
2. 함수 안에서 await를 사용할 수 있습니다.
await
프라미스 앞에 await 키워드를 붙이면 자바스크립트는 프라미스가 처리될 때까지 대기합니다.
처리가 완료되면 조건에 따라 아래와 같은 동작이 이어집니다.
에러 발생 – 예외가 생성됨(에러가 발생한 장소에서 throw error를 호출한 것과 동일함)
에러 미발생 – 프라미스 객체의 result 값을 반환
- await는 최상위 레벨 코드에서 작동하지 않습니다.
async/await
함께 사용하면 읽고, 쓰기 쉬운 비동기 코드를 작성할 수 있습니다.
async/await를 사용하면 promise.then/catch가 거의 필요 없습니다.
하지만 가끔 가장 바깥 스코프에서 비동기 처리가 필요할 때같이 promise.then/catch를 써야만 하는 경우가 생기기 때문에 async/await가 프라미스를 기반으로 한다는 사실을 알고 계셔야 합니다.
여러 작업이 있고, 이 작업들이 모두 완료될 때까지 기다리려면 Promise.all을 활용할 수 있다는 점도 알고 계시기 바랍니다.
- async/await, ajax: 보러가기
# 환경
/**
* tool: STS 4.13.0
* version: 2.7.3-SNAPSHOT
* java: 1.8
* type: MAVEN
* view: THYMELEAF
* jQuery: 3.6.0
*/
# 페이지
# HTML
<h1>동기/비동기 테스트 페이지 입니다.</h1>
<div>
<input id="toggle" type="button" onclick="toggle()" value="START" style="display: inline;"/>
<br>
<h3>SAMPLE CODE</h3>
<input type="button" onclick="console.log(type1())" value="TYPE1" style="display: inline;"/>
<input type="button" onclick="console.log(type2())" value="TYPE2" style="display: inline;"/>
<input type="button" onclick="console.log(type3())" value="TYPE3" style="display: inline;"/>
<input type="button" onclick="console.log(type4())" value="TYPE4" style="display: inline;"/>
</div>
# 4초 딜레이 함수, 2초 딜레이 함수, 발진기 함수(1초마다 타임스탬프로그.)
/** 4초 지연함수 */
function resolveAfter2Seconds() {
console.log(timestamp(), ':', "starting 4초 함수");
return new Promise(resolve => {
setTimeout(function() {
resolve(4000);
console.log(timestamp(), ':', "4초 함수 is done");
}, 4000);
});
}
/** 2초 지연함수 */
function resolveAfter1Second() {
console.log(timestamp(), ':', "starting 2초 함수");
return new Promise(resolve => {
setTimeout(function() {
resolve(2000);
console.log(timestamp(), ':', "2초 함수 is done");
}, 2000);
});
}
let isRun = false;
let interval = null;
function toggle() {
if(isRun) {
isRun = false;
clearInterval(interval);
$('#toggle').val('START');
} else {
isRun = true;
interval = setInterval(function() {
console.log('ING:', timestamp());
}, 1000);
$('#toggle').val('STOP');
}
}
/** 1초 마다 시간 로그! */
function timestamp() {
const date = new Date();
const hh = String(date.getHours()).padStart(2, '0');
const mi = String(date.getMinutes()).padStart(2, '0');
const ss = String(date.getSeconds()).padStart(2, '0');
return `${hh}:${mi}:${ss}`;
}
1. resolveAfter2Seconds (함수이름은 2초지만 4초로 변경함.)
- 시작로그: starting 4초 함수
- 종료로그: 4초 함수 is done
- 응답로그: 4000
2. resolveAfter1Second (함수이름은 1초지만 2초로 변경함.)
- 시작로그: starting 2초 함수
- 종료로그: 2초 함수 is done
- 응답로그: 2000
3. toggle
- on 일 경우, 1초마다 현재 시간 log를 남김. >> 비동기 여부 확인을 위해
- 로그패턴: ING: 23:59:59
# TYPE 1 (sequential)
function type1() {
sequentialStart(); // 2초 후 로그 "느림" 후 1초 후 "빠름"
return timestamp() + " : " + '==SEQUENTIAL END==';
}
async function sequentialStart() {
console.log(timestamp(), ':', '==SEQUENTIAL START==');
// 대기 연산자 뒤에 오는 식의 값이 약속이 아닌 경우 확인된 약속으로 변환됩니다.
const slow = await resolveAfter2Seconds();
console.log(timestamp(), ':', slow);
const fast = await resolveAfter1Second();
console.log(timestamp(), ':', fast);
}
/* LOG
ING: 21:23:22
ING: 21:23:23
21:23:23 : ==SEQUENTIAL START==
21:23:23 : starting 4초 함수
21:23:23 : ==SEQUENTIAL END==
ING: 21:23:24
ING: 21:23:25
ING: 21:23:26
ING: 21:23:27
21:23:27 : 4초 함수 is done
21:23:27 : 4000
21:23:27 : starting 2초 함수
ING: 21:23:28
ING: 21:23:29
21:23:29 : 2초 함수 is done
21:23:29 : 2000
ING: 21:23:30
ING: 21:23:31
*/
- 호출된 함수는 바로끝나지만, 비동기로 함수가 진행.
- 4초 함수가 다 끝난 이후, 2초 함수가 시작된다.
- 함수명 그대로 순차적을 진행된다!
# TYPE 2 (concurrent)
function type2() {
concurrentStart(); // 2초 후 로그 "느림" 후 "빠름"
return timestamp() + " : " + '==CONCURRENT END with await==';
}
async function concurrentStart() {
console.log(timestamp(), ':', '==CONCURRENT START with await==');
const slow = resolveAfter2Seconds(); // 타이머를 즉시 시작합니다.
const fast = resolveAfter1Second();
console.log(timestamp(), ':', await slow);
console.log(timestamp(), ':', await fast); // 이미 빠르게 완료되었음에도 불구하고, 천천히 끝날 때까지 기다립니다.
}
/*
ING: 21:24:28
ING: 21:24:29
21:24:30 : ==CONCURRENT START with await==
21:24:30 : starting 4초 함수
21:24:30 : starting 2초 함수
21:24:30 : ==CONCURRENT END with await==
ING: 21:24:30
ING: 21:24:31
21:24:32 : 2초 함수 is done
ING: 21:24:32
ING: 21:24:33
21:24:34 : 4초 함수 is done
21:24:30 : 4000
21:24:34 : 2000
ING: 21:24:34
ING: 21:24:35
*/
- 호출된 함수는 4초함수, 2초함수가 비동기로 실행되고 바로 종료된다.
- 동시에 시작되어 2초 함수가 먼저 종료되고, 4초 함수가 종료된다.
- 2초함수가 먼저 끝났지만, await slow 에서 4초 함수가 끝나길 기다린다.
- 함수명 그대로 동시에 진행된다!
# TYPE 3 (stillConcurrent)
function type3() {
stillConcurrent(); // concurrentStart와 동일
return timestamp() + " : " + '==CONCURRENT END with Promise.all==';
}
function stillConcurrent() {
console.log(timestamp(), ':', '==CONCURRENT START with Promise.all==');
Promise.all([resolveAfter2Seconds(), resolveAfter1Second()]).then((messages) => {
console.log(timestamp(), ':', messages[0]); // slow
console.log(timestamp(), ':', messages[1]); // fast
});
}
/*
ING: 21:25:12
ING: 21:25:13
21:25:14 : ==CONCURRENT START with Promise.all==
21:25:14 : starting 4초 함수
21:25:14 : starting 2초 함수
21:25:14 : ==CONCURRENT END with Promise.all==
ING: 21:25:14
ING: 21:25:15
21:25:16 : 2초 함수 is done
ING: 21:25:16
ING: 21:25:17
21:25:18 : 4초 함수 is done
21:25:18 : 4000
21:25:18 : 2000
ING: 21:25:18
ING: 21:25:19
*/
- 함수명 그대로 TYPE2와 실행결과는 동일하다.
- 다만 함수에 async가 붙지않고, 변수의 await을 사용하지 않는다.
- 대신 Promiss.all과 then() 함수를 이용.
# TYPE 4 (parallel)
function type4() {
parallel(); // 진정한 병렬: 1초 후, 로그 "빠름" 후, 1초 후, "느림"
return timestamp() + " : " + '==PARALLEL with Promise.then END==';
}
function parallel() {
console.log(timestamp(), ':', '==PARALLEL with Promise.then==');
resolveAfter2Seconds().then((message)=>console.log(timestamp(), ':', message));
resolveAfter1Second().then((message)=>console.log(timestamp(), ':', message));
}
/*
ING: 21:26:57
ING: 21:26:58
21:26:58 : ==PARALLEL with Promise.then==
21:26:58 : starting 4초 함수
21:26:58 : starting 2초 함수
21:26:58 : ==PARALLEL with Promise.then END==
ING: 21:26:59
ING: 21:27:00
21:27:00 : 2초 함수 is done
21:27:00 : 2000
ING: 21:27:01
ING: 21:27:02
21:27:02 : 4초 함수 is done
21:27:02 : 4000
ING: 21:27:03
ING: 21:27:04
*/
- TYPE2 와 TYPE3 과 흡사하다.
- 호출된 함수는 4초함수, 2초함수가 비동기로 실행되고 바로 종료된다.
- 동시에 시작되어 2초 함수가 먼저 종료되고, 4초 함수가 종료된다.
- 다른 점은 4초 함수가 끝나길 기다리지 않고 바로 실행한다.
- 일반 ajax {async: ture} 와 비슷. (=또는 fetch)
# 내용
jQuery ajax를 사용하면서 비동기로 처리되는 ajax를 동기적으로 움직이게 만드려면 해당 스킬이 사용되면 좋을 거 같다.
# JavaScript 시리즈
https://hjho95.tistory.com/21 async, await
https://hjho95.tistory.com/22 async, await를 이용한 ajax
# JavaScript 시리즈의 참조 페이지
async/await: https://ko.javascript.info/async-await
'자바스크립트' 카테고리의 다른 글
[JavaScript] html dom 성능개선 관련 async defer 적용하기! (2) | 2022.09.10 |
---|---|
[JavaScript] async, await를 이용한 ajax 통신 (0) | 2022.09.10 |
[Vanilla JS] fetch - POST, application/json 로 요청하기! (0) | 2022.09.04 |
[Vanilla JS] fetch - POST, application/x-www-form-urlencoded 로 요청하기! (0) | 2022.09.04 |
[Vanilla JS] fetch - GET, application/x-www-form-urlencoded 로 요청하기! (0) | 2022.09.04 |