- 사용되거나 사용하지 않는 스크립트 추적 가능
- script로 여러개를 불러오는 것은 순서가 중요하지만
import로 불러오는 경우 순서는 무관- script src와 다르게 전역오염이 일어나지 않는다.
- 이벤트 리스너 : 두번째인자가 바로 실행되지 않고 이벤트가 발생할 때 실행
- setTimeout
- setInterval
- XMLHttpRequest
sync 방식은 콜백지옥이 나는 async에 비해 가독성이 좋지만 응답이 오기전까지 브라우저가 굳는 안좋은 결과가 발생하기 때문에 사용을 지양한다.
ex) Api 조회 한다고 10초 걸리는데 이 10초간 브라우저가 먹통 상태
콜백지옥을 벗어나기 위한 비동기 작업 제어를 위해 사용
resolve 또는 reject를 반환하고 이를 처리하기 위해 .then / .catch / .finally 3가지의 메소드가 존재한다.
여전히 Promise에서 쓰이는 불편한 부분을 코드 실행을 순차적으로 실행하게 만드는 역할을 해준다.
function firstCallback(){
const first = 'first'
setTimeout(()=>{secondCallback(first)},1000)
}
function secondCallback(data){
const second = 'second'
setTimeout(()=>{thirdCallback(data + ' ' + second)},1000)
}
function thirdCallback(data){
const third = 'third'
setTimeout(()=>{console.log(data + ' ' + third)},1000)
}
firstCallback();
function first(){
const first = 'first'
return new Promise((resolve,reject)=>{
setTimeout(()=>{
resolve(first)
},1000)
})
}
function second(data){
const second = 'second';
return new Promise((resolve,reject)=>{
setTimeout(()=>{
resolve(data + ' ' + second)
},1000)
})
}
function third(data){
const third = 'third';
return new Promise((resolve,reject)=>{
setTimeout(()=>{
resolve(data + ' ' + third)
},1000)
})
}
first().then((data)=>second(data)).then((data)=>third(data)).then(result=>console.log(result))
function asyncFirst(){
const first = 'first';
return new Promise((resolve)=>setTimeout(()=>resolve(first),1000))
}
function asyncSecond(val){
const second = 'second';
return new Promise((resolve)=>setTimeout(()=>resolve(val + ' ' + second),1000))
}
function asyncThird(val){
const third = 'third';
return new Promise((resolve)=>setTimeout(()=>resolve(val + ' ' +third),1000))
}
async function asyncAll(){
const firstVal = await asyncFirst();
const secondVal = await asyncSecond(firstVal);
const thirdVal = await asyncThird(secondVal);
console.log(thirdVal);
}
asyncAll();
위의 3가지 경우 모두 같은 결과이다.
이를 Callback으로 하면 콜백지옥에 빠지고
Promise를 하면 순차적이긴 하지만 좀 더 직관적인 순차가 부족하고
이를 보완해주는 것이 async await이다.
Promise의 경우 .catch를 사용하고
async await은 해당 await 부분을 try { }로 묶고 그아래 catch()를 처리한다.
각각의 API를 처리하고 전부 끝나면 값을 반환한다.
const promise1 = new Promise((resolve) => {
setTimeout(() => {
resolve(1);
}, 3000);
});
const promise2 = new Promise((resolve) => {
setTimeout(() => {
resolve(2);
}, 2000);
});
const promise3 = Promise.reject(3);
Promise.all([promise1, promise2, promise3])
.then((result) => console.log(result))
.catch((e) => console.error(e));
return Promise.all([
Promise.resolve(productOptions),
Promise.all(
productOptions.map(productOption => request(`/product-option-stocks?productOption.id=${productOption.id}`))
)])
- 안쪽 Promise.all에서 여러 url에 대해 request를 진행하였고
- Promise.resolve(productOptions)부분도 함께 리턴하기 위해 Promise.all을 사용했다.
각각의 API를 처리하고 배열형태로 각각의 처리값을 합쳐 반환한다.
const promise1 = new Promise((resolve) => {
setTimeout(() => {
resolve(1);
}, 3000);
});
const promise2 = new Promise((resolve) => {
setTimeout(() => {
resolve(2);
}, 2000);
});
const promise3 = Promise.reject(3);
Promise.allSettled([promise1, promise2, promise3])
.then((result) => console.log(result))
.catch((e) => console.error(e));
[
{ status: 'fulfilled', value: 1 },
{ status: 'fulfilled', value: 2 },
{ status: 'rejected', reason: 3 }
]
resolve든 reject든 가장 빠른 API 동작 하는 것이 끝나면 바로 끝낸다.
const promise1 = new Promise((resolve, reject) => {
setTimeout(resolve, 500, 'one');
});
const promise2 = new Promise((resolve, reject) => {
setTimeout(reject, 100, 'two');
});
Promise.race([promise1, promise2]).then((value) => {
console.log(value);
});
resolve대상으로 가장 빠른 API 동작 하는 것이 끝나면 바로 끝낸다.
const promise1 = new Promise((resolve, reject) => {
setTimeout(resolve, 500, 'one');
});
const promise2 = new Promise((resolve, reject) => {
setTimeout(reject, 100, 'two');
});
Promise.any([promise1, promise2]).then((value) => {
console.log(value);
});
let a = [1,3,5,4,2]
function x(arr){
arr.sort();
}
x(a);
console.log(a);
의도하지않은 외부 함수인 a에까지 영향을 주는 해당 코드는 지양하고
function x(arr){
arr = Array.from(arr).sort();
}
이렇게 수정할 경우 참조한 매개변수인 외부변수는 값이 변하지 않는다.
Promise의 all메소드 말고 race, any allSettled이라는 것을 새롭게 알 수 있었고 전반적인 비동기를 복습할 수 있었다.