
function loadScript(src, callback) {
let script = document.createElement('script');
script.src = src;
// 로딩에 성공하면 이걸 로드
script.onload = () => callback(null, script);
// 로딩에 실패하면 이걸 로드
script.onerror = () => callback(new Error(`${src}를 불러오는 도중에 에러가 발생했습니다.`));
document.head.append(script);
}
// 에러 핸들링 가능!
loadScript('/my/script.js', function(error, script) {
if (error) {
// 에러 처리
} else {
// 스크립트 로딩이 성공적으로 끝남
}
});
.then(f,f)으로 받았을 때, resolve함수는 첫번째 함수를, reject함수는 두번째 함수를 실행한다 .then(f)에 하나의 인자만 넣으면 된다.catch(f)로 받거나, .then(n,f)의 첫번째 인자에 null을 넣으면 된다 (catch를 주로 사용하는 이유는 문법상의 간결성 때문!)Finally는 프로미스의 처리 결과를 모름 그냥 실행됨// 이건 f1을 수행하면서 난 에러를 받음
promise.then(f1).catch(f2);
// 이건 처음부터 정의된 reject함수만 실행시킬 뿐, f1을 수행할 때 난 에러는 받지 못함
promise.then(f1, f2);
Promise.allSettled자주 쓰임.all,race도 꽤 빈번히 쓰임!allSettled의 장점은rejected된 정보도 담겨서 나온다는 거.all같은 경우 하나라도 실패하면 거기서 멈춘다.
promise의 병렬처리가 중요하기 때문에 이 아이들이 중요하다. 3초 걸리는 비동기 함수 1000개를 순차적으로 실행시키면 3000초가 걸리지만, 병렬적으로 실행시키면 3초가 걸린다.
Promise.all(promises) – 모든 프라미스가 이행될 때까지 기다렸다가 그 결괏값을 담은 배열을 반환합니다. 주어진 프라미스 중 하나라도 실패하면 Promise.all는 거부되고, 나머지 프라미스의 결과는 무시됩니다.Promise.allSettled(promises) – 최근에 추가된 메서드로 모든 프라미스가 처리될 때까지 기다렸다가 그 결과(객체)를 담은 배열을 반환합니다. 객체엔 다음과 같은 정보가 담깁니다.Promise.race(promises) – 가장 먼저 처리된 프라미스의 결과 또는 에러를 담은 프라미스를 반환합니다.Promise.resolve(value) – 주어진 값을 사용해 이행 상태의 프라미스를 만듭니다.Promise.reject(error) – 주어진 에러를 사용해 거부 상태의 프라미스를 만듭니다.그렇지만 이벤트 큐에 너무 많은 게 쌓이는 경우(스크롤 이벤트 등..) -> 우린 유동적으로 센스있게 시간을 건다던가 등의 방식을 택할 수 있음
// Synchronous
[1,2,3,4].forEach(function(i) {
console.log(i);
});
// Asynchronous
function asyncForEach(array, cb) {
array.forEach(function(){
setTimeout(cb, 0);
});
}
asyncForEach([1,2,3,4], function(i){
console.log(i);
});
const delay = () => {
const randomDelay = Math.floor(Math.random() * 4) * 100
return new Promise(resolve => setTimeout(resolve, randomDelay))
}
const list = [1, 2, 3, 4, 5]
// 순서대로
const printDataSerial = async () => {
for (let data of list) {
await delay().then(() => console.log(data))
}
}
// 순서 무작위 => forEach가 불리는 시점에 한번에 다 프로미스가 실행되어버림 (병렬적으로)
const printDataPare = async () => {
list.forEach(async data => {
await delay().then(() => console.log(data))
})
}
//받은 시간 뒤에 출력
const delayTimeOut = async (text, time) => {
setTimeout(() => {
console.log('타임아웃' + text)
},time)
}
// 1초 뒤에 일단 콘솔 찍고 res에 빈 값 보냄
const delayPromise = async (text) => {
return new Promise((res) => {
setTimeout(() => {
console.log('프라미스' + text)
res()
},1000)
})
}
const a = async () => {
console.log(1)
await delayTimeOut('첫번째', 1000)
console.log(2)
await delayPromise('첫번째')
console.log(3)
}
/*
a 결과
1
2
타임아웃 첫번째
프로미스 첫번째
3
*/
const b = async () => {
console.log(1)
delayTimeOut('첫번째', 1000)
console.log(2)
delayPromise('첫번째')
console.log(3)
}
/*
b 결과
1
2
3
타임아웃 첫번째
프로미스 첫번째
*/
const c = async () => {
console.log(1)
await delayPromise('첫번째', 1000)
await delayTimeOut('첫번째')
console.log(2)
}
/*
c 결과
1
프로미스 첫번째
2
타임아웃 첫번째
*/
const d = async () => {
console.log(1)
await delayTimeOut('첫번째', 1001)
console.log(2)
await delayPromise('첫번째')
console.log(3)
}
/*
d 결과 -> 1ms는 시간 차이를 인지하지 못하기 때문에
const d = async () => {
console.log(1)
await delayTimeOut('첫번째', 1000)
console.log(2)
await delayPromise('첫번째')
console.log(3)
}
의 결과와 같다
------------------------
1
2
타임아웃 첫번째
프로미스 첫번째
3
*/
const e = async () => {
console.log(1)
await delayTimeOut('첫번째', 1002)
console.log(2)
await delayPromise('첫번째')
console.log(3)
}
/*
e 결과 - 2ms차이는 인지하므로 결과가 달라진다
1
프로미스 첫번째
2
타임아웃 첫번째
*/
const [data,setData] = useState("")
const getData = async () => {
const tempData = await axios.get()
setData(tempData)
}
useEffect(()=>{
getData() // 여기에 await를 쓰면 뒤의 렌더링 막히므로 백그라운드에서 실행되도록 await를 쓰지 않는다.
//다른 어떤 행위들
},[])
let num = 1
const wait = (time) => {
return new Promise((res) => {
setTimeout(() => {
console.log(num ++ )
res()
}, time)
})
}
// 순서대로 실행된다.
async function a() {
await wait(1000);
console.log('지나가는중')
await wait(2000);//2
console.log('done')
}
// 불리는 동시에 실행된다.
async function b() {
const wait1 = wait(1000); //이행
const wait2 = wait(2000); //이행
await wait1;
console.log('지나가는중')
await wait2;
console.log('done')
}
a()