[ 목표 ]
- 세 대의 차를 아반떼>소나타>제네시스 순서대로 출발시킨다.
- 출발할때 GO!라는 텍스트를 표시한다.
- 도착할때 END!라는 텍스트를 표시한다.
- 한대의 차가 출발하고 도착하고나서 다음 차가 출발하게 한다.
- 3대의 차가 도착하고나면 경기끝!이란 텍스트를 표시한다.
시도 1) 우선 콜백함수를 차례대로 생성해서 출력값을 만들어서 결과값을 보자.
const 아반떼 = () => {
console.log('아반떼 GO!')
setTimeout(()=>console.log('아반떼 END!'),1000)
}
const 소나타 = () => {
console.log('소나타 GO!')
setTimeout(()=>console.log('소나타 END!'),1000)
}
const 제네시스 = () => {
console.log('제네시스 GO!')
setTimeout(()=>console.log('제네시스 END!'),1000)
}
아반떼()
소나타()
제네시스()
console.log('경기끝')
setTimeout()이 비동기 작동을 하는 콜백함수인 것을 잊는다면 아마 맨 마지막에 '경기끝'이 생길거라고 예상할 것이다.
동기적 함수가 모두 실행되고 나서야 결과값이 나오는 비동기 함수임을 기억하자. 결과는 다음과 같다.
아반떼 GO!
소나타 GO!
제네시스 GO!
경기끝
아반떼 END!
소나타 END!
제네시스 END!
시도 2) 호출코드 인자에 호출코드를 넣기
아반떼(소나타(제네시스()))
console.log('경기끝')
---------------------
//결과
제네시스 GO!
소나타 GO!
아반떼 GO!
경기끝
제네시스 END!
소나타 END!
아반떼 END!
인자를 먼저 읽는 함수의 특징때문에 가장 안쪽에 있는 제네시스부터 실행이 된다.
동적인 함수 console.log()가 먼저 실행되고, 비동기적 함수는 테크스 큐에 쌓인다.
밖으로 나와서 소나타가 실행되고, 아반떼가 실행이 된다.
동기적 함수가 다 끝난후 테스크 큐에 쌓인 데이터가 이벤트 루프를 타고 실행이 된다.
먼저 들어간 데이터가 먼저 나오는 큐의 특성에 따라 제일 먼저 쌓인 제네시스가 출력된다.
차례차례 소나타, 아반떼가 출력이 된다.
[알게된 것]
1. 어떻게 집어넣던지 무조건 동기적 함수가 먼저 출력된다
2. 동시에 출발하고, 아반떼>소나타>제네시스 순서로 출력된다. : 이 순서대로 함수를 배치한다.
3. 가장 마지막에 '경기끝'이 출력된다 : 동기적함수인 console.log(경기끝)을 비동기적 함수 안에 넣어서 먼저 실행되지 않게한다.
시도 3) 콜백 함수 안에 콜백함수 넣기
const callback = () => {
console.log('경기끝')
}
const 아반떼 = () => {
console.log('아반떼 GO!')
setTimeout(()=>{
console.log('아반떼 END!')
},1000)
}
const 소나타 = () => {
console.log('소나타 GO!')
setTimeout(()=>{
console.log('소나타 END!')
},1000)
}
const 제네시스 = (callback) => {
console.log('제네시스 GO!')
setTimeout(()=>{
console.log('제네시스 END!')
},1000)
callback()
}
아반떼()
소나타()
제네시스()
------------------------------------
//출력 결과
아반떼 GO!
소나타 GO!
제네시스 GO!
경기끝
아반떼 END!
소나타 END!
제네시스 END!
콜백 함수의 매개변수에는 함수만 인자로 들어갈 수 있으니까, 경기끝 코드도 콜백함수로 만들어서 제네시스 코드 안에 넣어줬다.
제네시스(소나타(아반떼()))
매개변수 안에 넣어서 실행해도 출력값은 똑같았다.
그래도 출발하고 도착하는 순서는 맞췄다.
시도 4) 시도3에서 cb()를 출력코드가 포함된 비동기 함수 안에 넣기
const 제네시스 = (callback) => {
console.log('제네시스 GO!')
setTimeout(()=>{
console.log('제네시스 END!')
callback() // 바꾼 자리
},1000)
// 3번에서 callback()가 있던 자리
}
아반떼()
소나타()
제네시스(callback)
------------------------------------
//출력
아반떼 GO!
소나타 GO!
제네시스 GO!
아반떼 END!
소나타 END!
제네시스 END!
경기끝
경기끝 텍스트가 비로소 가장 마지막에 내려갔다.
같이 순서를 따라가려면 같은 비동기함수 안에 넣어야 한다는것을 알았다.
제네시스(소나타(아반떼(callback)))
------------------------------
//출력
아반떼 GO!
소나타 GO!
제네시스 GO!
아반떼 END!
경기끝
소나타 END!
---------> 에러발생
제네시스 END!
---------> 에러발생
아반떼()에게 callback을 인자로 줬기때문에 아반떼 END 후에 경기끝!이 생긴다.
나머지는 근데 왜 에러가 발생하는지 모르겠음. 이건 교수님에게 질문해야지.
시도 5) 호출형태를 콜백형태로 바꿔보기
아반떼(()=>{})
소나타(()=>{})
제네시스(()=>{callback()})
//아반떼()
//소나타()
//제네시스(callback())
//이 형태와 같은 결과
아무것도 없어서 ()로 생략한거지만, 콜백함수를 애로우 함수 형태로도 사용할 수 있다는 점을 생각했다.
이대로 출력해도 모양을 바꾸기 전과 출력값이 같은 것을 확인했다.
콜백 함수 안에 넣으면 순서대로 흐름이 생긴다는 점을 생각해서 다시 코드를 짰다.
function callback() {
console.log('경기끝')
}
const 아반떼 = (callback) => {
console.log('아반떼 GO!')
setTimeout(()=>{
console.log('아반떼 END!')
callback(); // 다음 함수를 사용하고 싶은 자리
},1000)
}
const 소나타 = (callback) => {
console.log('소나타 GO!')
setTimeout(()=>{
console.log('소나타 END!')
callback();
},1000)
}
const 제네시스 = (callback) => {
console.log('제네시스 GO!')
setTimeout(()=>{
console.log('제네시스 END!');
callback();
},1000)
}
아반떼 (() => {
소나타 (() => {
제네시스 (() => {
callback()
})
})
})
----------------------------------------
//출력
아반떼 GO!
아반떼 END!
소나타 GO!
소나타 END!
제네시스 GO!
제네시스 END!
경기끝
드디어 원하는 결과값이 나왔다.
'프로그래밍 > javacscript' 카테고리의 다른 글
[220129] promise를 활용한 자동차 레이싱 게임 (0) | 2022.02.27 |
---|---|
[220127] 변수와 프로퍼티의 차이, 구조 분해 할당 (0) | 2022.02.10 |
[220107] 익명함수, arrow함수, 함수가 생성되고 호출되는 순서 (0) | 2022.02.02 |
[220105] 콜스택과 메모리힙, 스택과 힙, 메모리 할당 순서 (0) | 2022.02.02 |
[220127] promise, then, resolve (0) | 2022.02.02 |
댓글