동기적 - 차례대로 실행됨 (그거하는 동안 다른거 못함)
비동기적 - 흐름이 멈추지 않기 때문에 동시에 여러작업 처리
기다리는 과정에서 다른 함수 호출가능
비동기 처리
function work(callback) {
setTimeout(() => { //비동기처리가능
const start = Date.now(); //현재 시간을 숫자 형태로 가져오는 내장 함수
for (let i = 0; i < 1000000000; i++) {} //1,000,000,000 번 루프돌고
const end = Date.now();
console.log(end - start + 'ms'); // 얼마나 걸렸는지 알려줌
callback(end - start)
}, 0); //실제론 4ms 이후에 수행됨 (브라우저가 설정한 최소값)
}
console.log('작업 시작!'); //1번째 실행
work((ms) => {
console.log('작업이 끝났어요!');
console.log(ms + 'ms가 걸렸다고 해요.');
}); //3번 실행
// 콜백함수 - 이 펑션이 끝나고 실행됐으면 하는거 설정할때 사용
//함수 타입의 값을 파라미터로 넘겨줘서, 파라미터로 받은 함수를 특정 작업이 끝나고 호출을 해주는 것을 의미
console.log('다음 작업'); //2번째
setTimeout(() => { },0); --> 비동기처리가능
콜백함수 - 이 펑션이 끝나고 실행됐으면 하는거 설정할때 사용
비동기 처리를 해야하는 경우
promise
function increaseAndPrint(n, callback) {
setTimeout(() => {
const increased = n + 1;
console.log(increased);
if (callback) {
callback(increased);
}
}, 1000);
}
increaseAndPrint(0, n => {
increaseAndPrint(n, n => {
increaseAndPrint(n, n => {
increaseAndPrint(n, n => {
increaseAndPrint(n, n => {
console.log('끝!');
});
});
});
});
});
n을 다섯번에 걸쳐 1초마다 1씩 더해서 출력하는 작업을 setTimeout 으로 구현 - 콜백지옥
const myPromise = new Promise((resolve, reject) => { //성공 할 때에는 resolve를 호출, 실패할 때에는 reject를 호출
setTimeout(() => {
resolve('n'); //n 반환
}, 1000); //1초뒤에 성공
});
myPromise.then(n => { //then - 프로미스 끝나고 실행할거 설정
console.log(n);
});
//성공할때
const myyPromise = new Promise((resolve, reject) => {
setTimeout(() => {
reject(new Error()); //에러 발샹
}, 1000);
});
myyPromise.then(n => {
console.log(n);
})
.catch(error => { //실패했을때 수행할 함수
console.log(error);
});
//실패할때 에러날떄
function increaseAndPrint(n) {
return new Promise((resolve, reject) => {
setTimeout(() => {
const value = n + 1;
if (value === 5) { //5되면 에러만듦
const error = new Error();
error.name = 'ValueIsFiveError'; //에러 이름지정가능
reject(error);
return;
}
console.log(value);
resolve(value); //1더한 값 반환
}, 1000); //1초뒤에 실행
});
}
increaseAndPrint(0)
.then(n => { // 이형식이랑 밑이랑 같음 파라미터랑 리턴하는 함수에서 쓰는 인자가 같기떄문에
return increaseAndPrint(n);
})
.then(increaseAndPrint)
.then(increaseAndPrint)
.then(increaseAndPrint)
.then(increaseAndPrint) //5는 안되게 설정하였기 때문에 에러잡힘
.catch(e => {
console.error(e);
});
then은 이렇게 뒤에 붙여서 여러개 연달아 사용가능
async/await - ES8
function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
async function process() { //펑션 선언항때 앞에 async 붙이고
console.log('안녕하세요!');
await sleep(1000); // 프로미스앞에 await 1초쉬고 실행
console.log('반갑습니다!');
}
process().then(() => {
console.log('작업이 끝났어요!');
});
async function makeError() {
await sleep(1000);
const error = new Error();
throw error; //throw로 에러발생
}
async function process() {
try { //에러를 잡아낼 때에는 try/catch 문
await makeError();
} catch (e) {
console.error(e);
}
}
const getDog = async () => {
await sleep(1000);
return '멍멍이';
};
const getRabbit = async () => {
await sleep(500);
return '토끼';
};
const getTurtle = async () => {
await sleep(3000);
return '거북이';
};
async function process() {
/*
이렇게하면 순서대로 진행됨 동기적 실행
const dog = await getDog(); //앞에 어웨잇 붙여야함
console.log(dog);
const rabbit = await getRabbit();
console.log(rabbit);
const turtle = await getTurtle();
console.log(turtle);
*/
const [dog, rabbit, turtle] = await Promise.all([ //프로미스 올을 사용해서 동시에 작업을 시작 - 이중에 하나라도 오류나면 에러발생
getDog(),
getRabbit(),
getTurtle()
]);
console.log(dog);
console.log(rabbit);
console.log(turtle);
}
process();
Promise.race
가장 빨리 끝난것 하나만의 결과값을 가져옴 - 가장빨리끝난게 에러나야 에러나고 아니면 에러안남 (쓸일 많지는 않음)
async function process() {
const first = await Promise.race([
getDog(),
getRabbit(),
getTurtle()
]);
console.log(first);
}
process();