동기와 비동기는 자바스크립트가 동작하는 방식과 매우 큰 관련이 있음
<자바스크립트의 싱글 스레드 작업 수행 방식>
자바스크립트는 코드가 작성된 순서대로 작업을 처리함
이전 작업이 진행중일때는 다음 작업을 수행하지 않고 기다림(블록킹 방식)
먼저 작성된 코드를 먼저 다 실행하고 나서 뒤에 작성된 코드를 실행한다.
-> 동기 방식의 처리
동기적 처리의 단점은 하나의 작업이 너무 오래 걸리게 될 시, 모든 작업이 오래 걸리는 하나의 작업이 종료되기 전까지 올 스탑되기 때문에, 전반적인 흐름이 느려진다. (웹 사이트에서 버튼 하나하나마다 30초씩 걸리면...😫)
-> 동기처리 방식의 문제점
<멀티 쓰레드>
싱글 쓰레드 방식을 이용하면서, 동기적 작업의 단점을 극복하기 위해 여러 개의 작업을 동시에 실행시킴
즉, 먼저 작성된 코드의 결과를 기다리지 않고 다음 코드를 바로 실행함 (논 블로킹 방식)
-> 비동기 작업
동시에 다 실행시켜버리면 작업들이 정상적으로 수행됐는지는 어떻게 확인, 결과? -> 콜백함수 붙여서 이용
function taskA(){
console.log("A 작업 끝");
}
taskA();
console.log("코드 끝");
// A 작업 끝
// 코드 끝
이렇게 수행되는 것이 동기적 방식
taskA 함수를 비동기적으로 바꿔보자
function taskA(){
setTimeout(()=>{
console.log("A TASK END");
},2000);
}
taskA();
console.log("코드 끝");
// 코드 끝
// A TASK END
자바스크립트에는 setTimeout()이라는 타이머를 만들 수 있는 내장 비동기 함수가 있음
setTimeout()에는 두 개의 파라미터가 들어감.
처음은 콜백함수, 두번째는 delay time(millisecond 단위 - 1000이 1초)
먼저 지시된 작업을 끝날 때까지 기다리지 않고 다음작업을 바로 실행해버리는 이 방식 -> 비동기 방식
function taskA(a,b,cb){//콜백이라는 의미의 cb
setTimeout(()=>{
const res = a+b; //지역 상수
cb(res);
},3000);
}
taskA(3,4,(res) => {
console.log("A TASK RESULT : ",res);
});
console.log("코드 끝");
// 코드 끝
// A TASK RESULT : 7
이렇게 비동기 처리의 결과 값을 이용해야 할때는 콜백함수를 전달해서 이용
function taskA(a,b,cb){//콜백이라는 의미의 cb
setTimeout(()=>{
const res = a+b; //지역 상수
cb(res);
},3000);
}
function taskB(a,cb){//콜백이라는 의미의 cb
setTimeout(()=>{
const res = a*2; //지역 상수
cb(res);
},1000);
}
taskA(3,4,(res) => {
console.log("A TASK RESULT : ",res);
});
taskB(7,(res) => {
console.log("B TASK RESULT : ",res);
});
console.log("코드 끝");
// 코드 끝
// B TASK RESULT : 14
// A TASK RESULT : 7
taskB가 taskA보다 먼저 출력되는 이유는 B는 1초 기다리고, A는 3초 기다리기 때문에 A보다 먼저 끝남
function taskA(a,b,cb){//콜백이라는 의미의 cb
setTimeout(()=>{
const res = a+b; //지역 상수
cb(res);
},3000);
}
function taskB(a,cb){//콜백이라는 의미의 cb
setTimeout(()=>{
const res = a*2; //지역 상수
cb(res);
},1000);
}
function taskC(a,cb){//콜백이라는 의미의 cb
setTimeout(()=>{
const res = a*-1; //지역 상수
cb(res);
},2000);
}
taskA(3,4,(res) => {
console.log("A TASK RESULT : ",res);
});
taskB(7,(res) => {
console.log("B TASK RESULT : ",res);
});
taskC(14,(res) => {
console.log("C TASK RESULT : ",res);
});
console.log("코드 끝");
// 코드 끝
// B TASK RESULT : 14
// C TASK RESULT : -14
// A TASK RESULT : 7
function taskA(a,b,cb){//콜백이라는 의미의 cb
setTimeout(()=>{
const res = a+b; //지역 상수
cb(res);
},3000);
}
function taskB(a,cb){//콜백이라는 의미의 cb
setTimeout(()=>{
const res = a*2; //지역 상수
cb(res);
},1000);
}
function taskC(a,cb){//콜백이라는 의미의 cb
setTimeout(()=>{
const res = a*-1; //지역 상수
cb(res);
},2000);
}
taskA(4,5,(a_res) => {
console.log("A RESULT : ",a_res);
taskB(a_res,(b_res) => {
console.log("B RESULT : ",b_res);
taskC(b_res,(c_res) => {
console.log("C RESULT : ",c_res);
});
});
});
console.log("코드 끝");
// 코드 끝
// A RESULT : 9
// B RESULT : 18
// C RESULT : -18
콜백함수의 콜백함수의 콜백함수를 넣어서 비동기 처리의 결과를 또 다른 비동기 처리의 값으로 전달 가능
-> 가독성 안좋음
비동기 처리의 결과를 또 다른 비동기 처리의 결과로 계속 이용하는 로직이 계속 길어지면
-> 콜백 지옥