동기적이란 각 참여자가 즉시(또는 가능한 한 즉시) 메시지를 수신(필요시 처리 및 회신)하는 실시간 통신을 의미합니다
비동기라는 용어는 둘 이상의 객체 또는 이벤트가 동시에 존재하지 않거나 발생하지 않는 경우(또는 이전 객체 또는 이벤트가 완료될 때까지 기다리지 않고 발생하는 여러 관련 작업)를 말합니다.

javascript은 싱글 스레드 언어(실행을 처리하는게 하나(call stack))이기 때문에 콜스택에 실행컨텍스트가 남아있는 동안 브라우저는 아무것도 할 수가 없다. 당장 처리하기 힘든 애들은 비동기식 처리를 하는 것이다.
Web API : 웹 브라우저에서 제공하는 API로 AJAX나 Timeout등의 비동기 작업을 실행
Task Queue : Callback Queue라고도 하며 Web API에서 넘겨받은 Callback함수를 저장(선입선출 방식)
Event Loop : Call Stack이 비어있다면 Task Queue의 작업을 Call Stack으로 옮김
function a() {
c(); // return address(복귀 주소)
console.log(`a function!!`);
}
function b() {
setTimeout(() => {
console.log(`1초후 setTimeout 함수 실행!!`);
// 동기식이었으면 1초후 setTimeout에 먼저 나와야했지만 비동기라 마지막 출력
// 시간을 안주더라도 제일 마지막 출력 -> setTimeout은 비동기식 함수이다.
}, 1000);
console.log(`b function!!`);
}
function c() {
b(); // return address(복귀 주소)
console.log(`c function!!`);
}
// c 실행 -> b 실행 후 c 복귀 -> a 복귀
a();
/**
b function!!
c function!!
a function!!
1초후 setTimeout 함수 실행!!
*/
함수 안에서 인자값으로 들어가는 익명 함수
// 비동기식 처리 방식에서 callback 함수 호출
// runIndelay(callback, seconds);
function runIndelay(callback, seconds) {
setTimeout(callback, seconds);
}
runIndelay(() => {
console.log(`타이머 3초 경과!!`);
}, 3000);
runIndelay(() => {
console.log(`타이머 1초 경과!!`);
}, 1000);
console.log(`-- 프로그램 종료 --`);
/**
-- 프로그램 종료 --
타이머 1초 경과!!
타이머 3초 경과!!
*
실행 순서
1. 동기 먼저 실행
2. Web API에 setTimeout(3초), setTimeout(1초)를 담아둔다
3. Web API에서 타이머를 세고 1초를 먼저 테스크 큐에 넣는다
4. Web API에서 타이머를 세고 3초를 테스크 큐에 넣는다
5. Event Loop는 call stack에 알리고 call stack이 비어있으면 테스크 큐에 있는 콜백 함수 전달 후 실행
결론: 순서가 앞에 오더라도 동기 먼저 실행 후 테스크 큐에 담긴 순서대로 실행
Promise 객체는 비동기 작업이 맞이할 미래의 완료 또는 실패와 그 결과 값을 나타냄
일종의 비동기 관리자같은 느낌
// 빌트인 클래스인 Promise를 통해 비동기식 처리
let promise1 = new Promise((resolve, reject) => {
// 실행한 비동기식 로직
});
promise1
.then(성공한 경우)
.catch(실패한 경우)
Tesk queue에 들어가 있다가 Event rupe로 돌아오는 시점에서
성공했다는 신호를 받으면 than이 인자로 받고 call stack에 결과를 알려줌
비동기 호출 순서는 위에서 아래 순서가 아닌 태스크 큐에 들어온 순서대로 호출하기 때문에 순차적으로 호출해서 실행이 필요한 경우 Promise를 사용할 수 있음
callback 함수 안에 callback 함수가 중첩되어 있을 경우 상위 함수가 하나라도 틀릴 시 아예 호출이 안되는 걸 체크하고 싶을 때도 Promise는 참 유용하다
function step1(init, callback) {
let result = init + 1;
callback(result);
}
function step2(init, callback) {
let result = init + 2;
callback(result);
}
function step3(init, callback) {
let result = init + 3;
callback(result);
}
step1(0, (result1) => {
console.log(`result1 = ${result1}`);
step2(result1, (result2) => {
console.log(`result2 = ${result2}`);
step3(result2, (result3) => {
console.log(`result3 = ${result3}`);
});
});
});
// 하나라도 작동 에러가 나오면 실행 불가
// 비동기식 처리 함수를 순차적으로 호출해서 실행하고자 할 때...
function step1(init) {
let result = init + 1;
// callback(result);
return Promise.resolve(result);
}
function step2(init) {
let result = init + 2;
// callback(result);
return Promise.resolve(result);
// return Promise().reject(error);
}
function step3(init) {
let result = init + 3;
// callback(result);
return Promise.resolve(result);
}
step1(0)
.then((result1) => {
console.log(`result1 = ${result1}`);
return step2(result1);
})
.then((result2) => {
console.log(`result2 = ${result2}`);
return step3(result2);
})
.then((result3) => {
console.log(`result3 = ${result3}`);
})
.catch((error) => console.log(error));
비동기식 처리 방식으로 네트워크를 통해 리소스를 가져옴
페치는 네트워크 리소스 접속 성공, 실패 여부를 프로미스에게 전담
잘 받아왔으면 프로미스가 성공을 반환, 실패시 error를 반환
전역 fetch() 메서드는 네트워크에서 리소스를 취득하는 절차를 시작하고, 응답이 사용 가능해지면 이행하는 프로미스를 반환합니다.
// API promise 리턴값 확인 후 호출
const url = "http://kobis.or.kr/kobisopenapi/webservice/rest/boxoffice/searchDailyBoxOfficeList.json?key=82ca741a2844c5c180a208137bb92bd7&targetDt=20120101";
fetch(url) // resolve(result), reject(error)
.then((result) => {
console.log(`result ==> ${result}`);
})
// result ==> [object Response]
.catch((error) => {
console.log(`error ==> ${error}`);
});
// error ==> TypeError: fetch failed