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()