05-2 함수 고급
1. 동기 VS 비동기
| 특징 | 장점 | 단점 | |
| 동기 | 요청을 보낸 후 응답을 받아야만 다음으로 넘어간다. |
설계가 간단하고 직관적이다 | 요청에 따른 결과가 반환되기 전까지 아무것도 못하고 대기해야한다. -->비효율 |
| 비동기 | 요청을 보낸 후 응답과 상관없이 다음으로 넘어간다. |
요청에 따른 결과가 반환되는 시간 동안 다른 작업을 할 수 있다. -->효율 |
설계가 복잡하다. |
<script>
function asyncTimer(time){
console.log('1')
console.log('2')
setTimeout(
function(){
console.log('3')
}, time*1000
)
console.log('4')
setTimeout(
function(){
console.log('5')
},time*500
)
}
asyncTimer(1)
</script>
<실행결과>
1
2
4
5
3
ㄴ 동기적으로 실행된다면 1과 2를 출력한 후 3이 출력될 때까지 1초를 기다릴 것이다.
그러나 자바스크립트는 비동기적으로 실행하므로 1초를 기다리는 동안 4를 출력하고
0.5초 후에 5를 출력하고 마지막으로 3이 출력된다.
2. 콜백 함수
1) 콜백 함수란?
setTimeout(
function(){
console.log('3')
}, time*1000
)
ㄴ 함수의 매개변수로 전달되는 함수를 콜백 함수라고 한다. 위에서는 function(){console.log('3')}가 콜백 함수이다.
2) 동기 콜백 함수와 비동기 콜백 함수
<script>
function printImmediately(print){
print()
console.log('world')
}
printImmediately(function () {console.log('hello')})
</script>
<실행결과>
hello
world
ㄴ console.log('hello') 함수는 printImmediately 함수에 매개변수로 전달되어 콜백 함수라고 할 수 있다.
또한 함수 호출 후 시간 지체 없이 바로 실행되었으므로 동기 콜백 함수라고 할 수 있다.
<script>
function printWithDelay(print,timeout){
setTimeout(print, timeout);
console.log("world")
}
printWithDelay(function (){console.log("hello")},1000)
</script>
<실행결과>
world
hello
ㄴ console.log("hello") 함수는 printWithDelay 함수에 매개변수로 전달되어 콜백 함수라고 할 수 있다.
함수 호출 후 console.log("world")를 먼저 실행하고 1초 뒤에 console.log("hello")가 실행이 되므로
비동기 콜백 함수라고 할 수 있다.
3) 콜백 지옥 탈출- Promise
콜백 함수 안에서 또 다른 콜백 함수를 호출을 반복하면서 코드의 길이가 길어지고 가독성이 떨어지는 경우를 콜백 지옥이라고 한다. 이러한 콜백 지옥을 탈출할 수 있는 대표적인 방법 중 하나가 promise 객체를 사용하는 것이다.
const promise = new Promise(function(resolve,reject){
//함수 실행
})
ㄴ Promise 객체가 전달하는 콜백 함수의 이름은 executor이고 promise가 생성되면 바로 실행된다.
이때 네트워크 통신 등 불필요한 함수 실행을 피할 수 있도록 코드를 작성해야 한다.
<script>
var promise = function (flag) {
return new Promise(function (resolve, reject) {
if (flag) {
resolve("resolved!");
} else {
reject("rejected!");
}
});
};
promise(true)
.then(function (result) {
console.log(result);
})
.catch(function (result) {
console.log(result);
});
promise(false)
.then(function (result) {
console.log(result);
})
.catch(function (result) {
console.log(result);
});
</script>
<실행결과>
resolved!
rejected!
ㄴ 성공적으로 실행하면 resolve 함수를 수행하고 .then 메소드로 연결되어 resolved! 를 결과로 출력한다.
에러가 발생하면 reject 함수를 수행하여 .catch 메소드로 연결되고 rejected!를 결과로 출력한다.
4) 콜백 지옥 탈출- async/await
async function (){
await asyncFunction1(){ ... }
await asyncFunction2(){ ... }
}
ㄴ 비동기 코드일지라도 async와 await를 사용하면 동기적으로 수행이 가능하다.
<script>
async function print() {
await timer(1, 3);
await timer(2, 1);
await timer(3, 2);}
function timer(num, time) {
setTimeout(function () {
console.log(num);
}, time * 1000);}
print()
</script>
<실행결과>
2
3
1
ㄴ async/await를 사용했지만 예상과 달리 비동기적인 실행으로 결과가 나타났다. Promise를 사용하지 않았기 때문이다.
async function print() {
await timer(1, 3)
.then(function (result) {
console.log(result);
})
.catch(function (result) {
console.log(result);
});
await timer(2, 1)
.then(function (result) {
console.log(result);
})
.catch(function (result) {
console.log(result);
});
await timer(3, 2)
.then(function (result) {
console.log(result);
})
.catch(function (result) {
console.log(result);
});
}
function timer(num, time) {
return new Promise(function (resolve, reject) {
setTimeout(console.log(num), time * 1000);
resolve("resolved!");
reject("rejected!");
});
}
print();
<실행결과>
1
'resolved!'
2
'resolved!'
3
'resolved!'
ㄴ Promise 객체를 사용하니 동기적으로 실행되었고 결과로 1,2,3 이 도출되었다.
3. 화살표 함수
(매개변수) => {
실행할 함수
}
ㄴ function 키워드 대신 화살표(=>) 를 사용하여 간단히 함수를 작성할 수 있다.
<script>
let numbers=[1,2,3,4,5,6]
numbers
.filter((value) => value % 2 === 0) --> 리턴하는 값이 true 인 것들만 모아서 새로운 배열 생성
.map((value) => value * value) --> 리턴한 값들을 기반으로 새로운 배열 생성
.forEach((value) => { --> 배열 내부의 요소를 사용하여 호출
console.log(value)
})
</script>
<실행결과>
4
16
36
ㄴ 위처럼 메소드가 리턴하는 값을 기반으로 함수를 줄줄이 사용하는 것을 메소드 체이닝이라고 한다.
4. 타이머 함수
| 함수 이름 | 설명 |
| setTimeout(함수, 시간) | 특정 시간 후에 함수를 한 번 호출한다 |
| setInterval(함수, 시간) | 특정 시간마다 함수를 호출한다 |
| clearTimerout(타이머_ID) | setTimeout() 함수로 설정한 타이머를 제거한다 |
| clearInterval(타이머_ID) | setInterval() 함수로 설정한 타이머를 제거한다 |
<script>
setTimeout(()=>{
console.log("1초 후에 실행됩니다")
},1000)
let count = 0
let id
id = setInterval(()=>{
console.log(`1초마다 실행됩니다(${count}번째)`)
count++
if(count === 5)
clearInterval(id)
},1000)
</script>
<실행화면>
1초 후에 실행됩니다
1초마다 실행됩니다(0번째)
1초마다 실행됩니다(1번째)
1초마다 실행됩니다(2번째)
1초마다 실행됩니다(3번째)
1초마다 실행됩니다(4번째)
'혼공스보면서 혼공스(JS)' 카테고리의 다른 글
| CH6. 객체- 객체의 속성과 메소드 사용하기 (0) | 2021.07.11 |
|---|---|
| CH6. 객체- 객체의 기본 (0) | 2021.07.10 |
| CH5. 함수- 함수의 기본 형태 (0) | 2021.07.08 |
| CH4. 반복문- 반복문 (0) | 2021.07.08 |
| CH4. 반복문- 배열 (0) | 2021.07.08 |