동기 작업 : 하나의 작업을 실행하고 마친 후에 작업을 순차적으로 실행
비동기 작업 : 메인 흐름은 멈추지 않은 상태에서 특정 작업들을
백그라운드에서 처리하며 동시에 처리하는 것 처럼 실행
const sayHello = () => {
console.log("안녕");
}
setTimeout(sayHello, 3000); // 순서 2
console.log("end"); // 순서 1
setTimeout은 비동기 함수로
주어진 시간 후에 특정 코드를 실행하도록 예약하지만
기다리는 동안 나머지 코드는 계속 실행된다..
즉 비동기적으로 동작하여 코드의 흐름을 블록하지 않고 다음 작업을 이어간다.
function increase(number, callback){
setTimeout(()=>{
const result = number + 10;
if(callback){ // callback = truthy
callback(result);
}
}, 1000);
}
increase(0, result=>{
console.log(result);
increase(result, result => {
console.log(result);
increase(result, result=> {
console.log(result);
})
})
})
여러번 순차적으로 결과물을 콜백 함수로 전달하기 위해서는
중첩을 사용해서 호출할 수 있다..
하지만 이러한 형태는 가독성도 좋지 않고, 유지보수도 힘들기 때문에
피해야 하는 패턴 중 하나이다.. 이러한 형태를 콜백 지옥이라고 한다..
시간이 오래 걸리는 작업을 처리하기 위해서
사용자 인터페이스가 중단되지 않기 위해서..
여러 작업을 동시에 처리하기 위해서
(실제로는 자바스크립트는 그렇게 동작하지 않지만, 이벤트 루프를 통해 동시에 처리되는 것 처럼 보임)
콜백 지옥을 해결하기 위해서
결국 느린 작업이 전체 프로그램의 흐름을 막지 않도록 하기 위함..
이러면 사용자에게 더 나은 경험을 제공할 수 있고,
특히 네트워크 요청, 파일 입출력, 타이머 같은 시간이 오래 걸리는 작업에서 큰 효과를 발휘한다..
promise 는 콜백 지옥과 같은 코드가 형성되지 않게
(비동기 통신 간의 순서를 정하기 쉽게) 하는 방안으로
ES6 에서 도입되었다..
promise 객체 생성 이유?
1. 비동기 처리 함수를 실행 시 성공, 실패에 대한 처리가 용이하다..
2. promise 객체가 제공하는 메소드를 사용하기 위함
(콜백 지옥 상황을 해소해 주기 때문.. 가독성이 좋고, 메소드 체이닝 방식 제공)
const increase = number => {
const promise = new Promise((resolve, reject)=>{
setTimeout(()=>{
const result = number + 10;
if(result > 50){
const e = new Error("numberToBig");
return reject(e); // return 생략 가능
}
resolve(result);
}, 1000);
});
return promise;
}
// Promise 객체 내부 내용을 동기로 처리한다. (기다려줌) 함수의 인자로 원하는 작업을 하고 값을 return해준다. - 성공 : resolve(값), 실패: reject(값)
console.log(increase(0)); // Promise { <pending> } // 값을 반환하는게 아니라 비동기로 처리한 약속자체를 반환해준다.
// 체이닝
// promise 객체는 then 메소드를 사용하여 비동기 작업의 결과를 처리할 수 있다..
increase(0).then(number => {
console.log(number)
return increase(number);
}).then(number => {
console.log(number);
return increase(number);
}).catch(e=>console.log(e, "가 발생했네")); // then() 인자로 결과값을 받아옴..
resolve 값 반환
-> increase() 의 인자값 40이하 넣었을 때 값 출력
reject 값 반환
-> increase() 의 인자값 41이상 일때 에러발생 catch에 넣어둔 값 발생
Error: numberToBig
at Timeout._onTimeout (c:\20240801-gangnam\07_react\04_async\src\01_intro\03_promise.js:17:27)
at listOnTimeout (node:internal/timers:581:17)
at process.processTimers (node:internal/timers:519:7) 가 발생했네
function increase (number){
const promise = new Promise((resolve, reject)=>{
setTimeout(()=>{
const result = number + 10;
if(result > 50){
const e = new Error("number to big");
return reject(e);
}
resolve(result);
}, 1000);
});
return promise;
}
// async : 비동기 함수를 정의
async function run(){
try{
// resolve 값 받음
let result = await increase(1); // await : 결과값을 기다렸다가 반환
console.log(result);
result = await increase(2);
console.log(result);
result = await increase(3);
console.log(result);
result = await increase(4);
console.log(result);
result = await increase(5);
console.log(result);
result = await increase(6);
console.log(result);
return result;
}catch(e){
// reject 값 받음
console.log(e, "가 발생함");
}
}
const value = async () => {
const runValue = await run();
console.log("value " + runValue);
}
const result = value();
/* console.log(result); // Promise { <pending> } */