반응형
자바스크립트에서 비동기 처리란 동기적 처리와 비교해서 얘기를 할 수 있겠는데
위 사진은 동기적처리에서의 작업연산 방식과 비동기적으로 처리 했을 때의 작업 연산 방식에 대해 나타내고 있는 사진이다.
동기적으로 작업을 처리하려 할 떄는 1번이 끝날 때 까지 2번은 대기 후 실행, 2번이 끝날 떄 까지 3번이 대기 후 실행식으로 이루어지게 된다.
하지만 비동기적으로 작업을 처리하게 되면 우리가 코드를 실행하면서 흐름이 끊기지 않게 된다. 1번실행이 안끝나도 2번,3번, 4번 작업이 이루어지게 된다.
위 사진으로 예를 들어 정리하면
동기적 처리 : 4명이 한팀인 계주 달리기 (바통주자가 와야지 다음주자가 뛰기 가능!!)
비동기적 처리 : 4명이서 100m 달리기 (요이 땅 하면 동시에 출발가능!!)
정도로 생각하고 차이점이 무엇인지 정도만 알고 있으면 되겠다.
코드를 보면서 한번 차이점을 알아보자~~
function test() {
const start = Date.now(); // 현재날짜를 숫자형태로 표시
for(let i = 0; i<100000000; i++){
}
const end = Date.now();
console.log(end-start + 'ms'); // 작업을 처리하는데 얼마나 걸린지 알게 해주는 함수
}
test();
console.log("다음 주자");
이런식으로 순서대로 test() 함수를 호출해주고 난 다음에 다음 주자를 출력해주는 함수인데 test() 함수내에서 반복문을 실행하는 작업이 끝나기 전에는 다음 주자를 출력해주지 않고 137ms 초 동안 작업을 끝내고 나서야지 찍히는 것을 볼 수가 있다.
function test() {
setTimeout(function (){
const start = Date.now(); // 현재날짜를 숫자형태로 표시
for(let i = 0; i<100000000; i++){
}
const end = Date.now();
console.log(end-start + 'ms');
},0)
}
console.log("이전 주자");
test();
console.log("다음 주자");
위의 방식은 setTimeout() 함수를 이용해서 비동기적으로 처리 할 수 있게 한 것인데 차이점이 바로 보일 것이다.
setTimeout() 을 써주게 되면 우리가 특정 작업을 백그라운드에서 실행을 하기 때문에 코드흐름을 막지 않고 동시에 다른 작업을 이어 갈 수 있게 해준다. 뒤에 '0' 이 들어간 자리는 본인이 정해줄 수 있는데 몇 ms 뒤에 작업을 실행시키겠다 라고 초 단위를 정해주는 부분이다.
원래동기적으로 처리 했다면 이전주자, xxx(ms), 다음주자 순으로 출력이 되었겠지만 작업수행을 백그라운드에서 따로 빼줘서 실행을 시켰기 때문에 위와 같은 결과를 나타내는 것을 볼 수가 있을 것이다.
이런 비동기 작업을 도와주는게 es6 에 나온 Promise 인데 한번 알아보자. 우리가 setTimeout 을 이용해서 비동기작업을 끝낸뒤에 어떤 작업을 실행시킬 떄는 콜백함수로 처리하는데 콜백함수의 콜백함수로 계속 흔히 '콜백지옥' 이라는 코드를 경험하게 될 것이다.
function increaseAndPrint(n , callblack){
setTimeout(() => {
const increased = n + 1;
console.log(increased);
if(callblack)
callblack(increased);
}, 1000)
}
increaseAndPrint(0, n => {
increaseAndPrint(n, n=>{
increaseAndPrint(n, n=> {
increaseAndPrint(n, n=> {
increaseAndPrint(n, n=> {
console.log('계산 끝..')
})
})
})
})
});
이렇게 1초에 1씩 증가되서 계산 되는 함수를 만들어봤는데 보다시피 콜백의 콜백을 호출하는 것을 볼 수 있다.
function increaseAndPrint(n) {
return new Promise((resolve, reject) =>{
setTimeout(()=>{
const value = n + 1;
if(value === 5){
const error = new Error();
error.name = 'value is five!!';
reject(error);
return;
}
console.log(value);
resolve(value);
},1000);
})
}
increaseAndPrint(0).then(n => {
return increaseAndPrint(n);
}).then(n => {
return increaseAndPrint(n);
}).then(n => {
return increaseAndPrint(n);
}).then(n => {
return increaseAndPrint(n);
}).then(n => {
return increaseAndPrint(n);
}).catch(e => {
console.error(e);
});
위의 코드는 Promise 를 이용해서 코드를 바꾸어 본것인데 파라미터로
reject 와 resolve == 성공헀을때 와 실패했을 때의 작업을 나타내느 값읋 받아주고 콜백함수안에 콜백함수를 지정해주는 것이 아니라 then() 메소드를 이용해서 작업을 수행시켜주는 것을 볼 수 있다. catch() 는 이제 reject (실패)했을 경우에 에러를 만들어내고 그 에러를 잡아 줄때 써주는 메소드인데 reject, resolve 같이 then 과 catch 세트로 알아두면 편하겠다.
Promise를 써줌으로써 보다 간결하고 비동기작업의 개수가 많아져도 코드의 깊이가 깊어지지 않게 하는 것을 확인 할 수가 있는데 반대로 불편한 점이 있는데
1.에러를 잡을 때 어떤 부분에서 에러가 발생했는지 파악하기 어렵다.
2.특정 조건에 따라 분기를 나누는 작업도 어렵다 (then 으로 계속 작업해주기 때문)
3. 특정 값을 공유해가면서 작업해 나가기가 번거롭다.
정도로 알아 두면 되겠당><!
*****************비동기 처리를 도와주는 것이 Promise 고 그 Promise 를 더 쉽게 써주게 도와주는 것이 있는데 바로 async와 await 문법이다. *****************
function sleep(ms) {
return new Promise(resolve =>
setTimeout(resolve, ms));
}
async function process() {
console.log('ㅎㅇㅎㅇ');
await sleep(1000);
console.log('어웨잇 개꿀!');
}
process();
이런 식으로 async 키워드를 함수 앞에 붙여주면 되고 await 은 Promise 앞에 붙여주게 되서 굳이 .then 을 통해서 호출해줄 필요가 없게 되고 작업의 분기점을 만드는 것도 보다 쉬워지게 된다.
기존 reject 와 catch 를 이용해서 에러를 잡아내는 것처럼 await 와 async 를 이용해서 간단히 에러를 잡아내보는 것도 해보자
function sleep(ms) {
return new Promise(resolve =>
setTimeout(resolve, ms));
}
async function makeError(){
await sleep(1000);
const error = new Error();
throw error;
}
async function process() {
try {
await makeError();
} catch (e){
console.error(e);
}
}
process();
이런식으로 makeError 함수에서 에러를 던져주고 (thorw) try, catch 문을 이용해서 에러를 호출해주면 된다.
동기적 처리 와 비동기적 처리, 비동기적 처리를 더 쉽게 도와주는 것이 Promise, 그 Promise 를 더 쉽게 사용하게 해주는 문법이 async, await 라고 간단히 정리 하면 되겠다!
반응형
'JavaScript & jQuery' 카테고리의 다른 글
append(), prepend()의 차이점 (1) | 2020.08.03 |
---|---|
<jQuery> 페이지 이동 시키기 (location.replace()) (0) | 2020.07.31 |
<javascript>텍스트 에디터, 텍스트 편집기 만들기 (1) | 2020.07.18 |
<javascript>객체 (비구조화 할당, 함수) (0) | 2020.07.18 |
<javascript>함수 (4) | 2020.07.15 |