promise / Synchronous Processing & Asynchronous Processing
Introduction
사실 나도 jsdeepdive를 뒷쪽은 못읽었다. 지금 1년전에 600페이지까지 10회독한게 마지막 ㅠ
암튼 그래서 아직 개념은 좀 부족하지만, promise로 동기 비동기 처리는 자주해봤고 얕게는 알기때문에 단순히 동기 비동기처리하는 방법을 포스팅하려고한다.
ㅅㅂ급한불이 너무많아서 딥다이브 언제 다시 공부할수 있을지 ㅠ
# 심심해서 뜯어봄
console.log(Promise);
nodejs에서 Promise 예약어를 콘솔로 출력해보면 Function이라고 나옴
좀 더 자세히 보기 위해서 브라우저 개발자도구에서 dir해보면
이렇게 Promise생성자함수객체를 대략적으로나마 볼 수 있는데, 파라미터로 받는 resolve와 reject도 들어있고
프로토타입에 밥먹듯 쓰는 then, catch, finally도 들어있다. 생성자함수로 만들어지는거니까 promise도 객체다.
객체 그는 도대체 한계가 어딜까
깊게는 아직 딥다이브 10회독을 못끝낸 상태기때문에 자세히는 모르겠고, 내가 평소 promise로 동기 비동기처리하는 방식을 포스팅하겠다.
암튼 프로미스는 저런 프로토타입메서드들을 가지고 생성자함수로 생겨나는 객체임.
# 프로미스를 간단하게 만들어보자~
const appointment = new Promise((res, rej) => {
console.log("무찌는 돼지야");
});
이런식으로 생성자 함수나 클래스처럼 new달고 만들 수 있음. Promise는 생성자함수? 같음. 객체를 만들어주는거임. 이 객체가 promise고.
참고로 생성자함수 Promise안에 인수로 전해주는건 함수객체여야함. 저기선 (res,rej)=>{console.~머시기} 이부분이 해당 함수객체를 메모리에 생성해주는 함수리터럴임. 만약 안쓰면 type에러일어남.
근데 이상한점이 있다.
단순히 appointment라는 변수에 프로미스를 할당해줬는데 출력창에는 promise안에 있는 console.log코드가 실행되서 출력이 나왔네?
promise는 선언하자마자 바로 안에있는 콜백함수가 실행되게 된다.
이걸 막기 위해선,
const func = () => {
const appointment = new Promise((res, rej) => {
console.log("무찌야!");
});
};
이렇게 부모함수 func를 만들어 안에서 promise를 선언해주면 된다. 정확히는 프로미스를 반환하는 함수를 자주 쓴다.
const func = () => {
return new Promise((res, rej) => {
console.log("무찌야!");
});
};
이런식으로 말이지.. async await도 사실 프로미스를 반환하는 함수다.
암튼 나는 프로미스만 쓸거면 프로미스를 반환하는 함수로 자주쓴다.
# 그럼 프로미스는 어떻게 쓰는거야?
const appointment = new Promise((res, rej) => {
console.log("무찌야!");
});
다시 이 코드로 돌아와서 프로미스에 매개변수로 콜백함수 리터럴을 전해주었다.
프로미스에 매개변수로 전해주는 콜백함수는 무조껀 두개의 파라미터를 써주어야한다. 이 쓰임새는 좀이따 설명할거임.
const callback = (res, rej) => {
console.log("무찌야!");
};
const appointment = new Promise(callback);
따라서 이렇게 써도 promise는 정상동작하게된다.
봐봐. 똑같지?
중요한점은 promise안에 있는 콜백함수는 무조껀 두개의 매개변수를 전달해줘야한다.
위에 console.dir로 출력했을때 resolve와 reject가 있는데 여기에서 쓰이는것 같음
# 프로미스 상태에 대해서 araboza (조올라 중요함. 이거몰라서 예전에 애먹음)
const appointment1 = new Promise((res, rej) => console.log("바보야"));
console.log(appointment1);
const appointment2 = new Promise((res, rej) => res("무찌"));
console.log(appointment2);
const appointment3 = new Promise((res, rej) => rej("도리"));
console.log(appointment3);
이 코드 출력 결과물을 보면
이렇게 첫번쨰, res(resolve)나 rej(reject)콜백함수를 호출 안하고 걍 콘솔로 바보야라고만 한 코드만 있는 promise는 pending상태란다.
두번쨰 promise는 res콜백함수로 '무찌'라는 인수로 넣은게 제대로 잘 보여진다.
세번쨰는 rejected상태이고 에러로 rej(reject)함수에 인수로 넣은 도리라는 메세지로 에러가 떠버렸다.
두번쨰 프로미스는 사실 fulfilled상태이다. nodejs에서는 정확히 안나와서 브라우저 개발자도구에서 써보면
모든 프로미스의 상태를 알 수 있다.
프로미스가 호출되고부터 상태가 정해지는데 pending상태라니.. 뭔가 느낌이 안좋은?느낌이지 않나?
프로미스 체이닝을 아래서 쓸건데 이 상태개념이 왜 있는지 알게될거임.
암튼 promise는 pending, fulfilled, rejected 세가지 상태가 존재함. (더있나?)
# promise 상태가 어떻게 변하는지 코드로 한번 araboza
const appointment = new Promise((res, rej) => {
setTimeout(() => {
res("무찌엉덩이");
}, 1000);
});
console.log("resolve가 호출되기전에는~", appointment, "상태야~");
setTimeout(() => {
console.log("resolve가 호출된후에는~", appointment, "상태야~");
}, 2000);
프로미스는 선언 할당 시점에서 만들어진다.
그리고 프로미스의 콜백함수내에서 resolve(res)콜백함수를 setTimeout함수를 사용해서 1초 후에 호출되게 했다.
때문에 첫번째 console.log(appointment)코드에서는 promise가 resolve()콜백함수를 호출하기 이전의 promise상태를 확인할 수 있고, 두번쨰 setTimeout함수에서는 2초후의, resolve콜백함수가 호출된 이후 promise의 상태를 확인 할 수 있다.
이 코드의 출력결과물을 보면
이렇단다. 사실 두번째 출력은 fulfilled상태인데 nodejs라서 저렇게뜸
브라우저에서 다시 해보면,
이렇게 된다.
이제 resolve가 아니라 reject콜백으로 호출해보면
역시나 reject콜백함수를 호출하기전에는 pending상태이다.
이 플로우를 그림으로 보자면,
promise가 선언 할당된 0초인 상태부터 resolve()콜백함수를 호출하기 전까지는 pending상태이다.
그리고 1초후에 resolve함수가 호출이 된 이후에는 promise의 상태는 fulfilled상태로 되는것이다.
마찬가지로 rejected상태도 reject()콜백으로 호출되기전에는 pending상태이다.
+ res콜백함수를 두번쓰면?
const appointment = new Promise((res, rej) => {
setTimeout(() => {
res("무찌엉덩이");
res("무찌궁뎅이");
}, 1000);
});
console.log("resolve가 호출되기전에는~", appointment, "상태야~");
setTimeout(() => {
console.log("resolve가 호출된후에는~", appointment, "상태야~");
}, 2000);
걍 처음 호출인 무찌엉덩이로 fulfilled상태로 변하는거다. 뒤에 resolve는 걍무시~ 호출된건지 아닌건지도모름
# 이걸 어떻게 사용할까? - 프로미스 체이닝 then
const appointment = new Promise((res) => {
setTimeout(() => {
res();
console.log("첫번째 프로미스 끝났어");
}, 1000);
}).then(() => {
console.log("then메서드에 넣은 콜백함수 호출됐어!");
});
then은 프로미스 뒤에 .then으로 쓸 수 있다. 프로미스 객체에 메서드로 있는거인듯?
암튼 이 메서드에 또 콜백함수 리터럴을 넣어줬음.
출력 결과물을 보면
이렇게 1초후에 res()와 console.log('첫번쨰 머시기~')코드가 실행되고 바로 then.에 넣은 콜백함수가 호출된다.
then뒤에 있는 콜백함수는 이전 promise가 pending상태에서 fulfilled상태가 될때까지 기다렸다가 실행된다는거임!!
이걸 그림으로 보면,
이렇게 동작을 하게되는것이다.
때문에 이걸로 우리는 동기처리를 할 수 있는거다.
+ 만약 resolve를 호출하지 않는다면?
const appointment = new Promise((res) => {
setTimeout(() => {
console.log("앙?");
}, 1000);
}).then(() => {
console.log("then메서드에 넣은 콜백함수 호출됐어!");
});
만약 이렇게 resolve를 호출하지 않으면, 이 프로미스는 영원히 pending상태이기 때문에 then에 들어있는 함수는 호출되지 않는다.
따라서 이 코드는 console.log('앙?')만 실행되고 then뒤로부터는 실행되지 않음
# reject는 어떨까?
const appointment = new Promise((res, rej) => {
setTimeout(() => {
console.log("프로미스 reject!");
rej("거절!");
}, 1000);
})
.then(() => {
console.log("여기는 then에 있는 콜백함수야");
})
.catch(() => {
console.log("여기는 catch에 있는 콜백함수야");
});
then뒤에 catch를 하나 더 붙여보았다. 만약 reject(rej)콜백을 호출하면 어떻게될까?
일단첫번째 console.log('프로미스 reject!')코드는 실행된다.
근데 rej()콜백함수를 호출하였더니
then안에 있는 콜백함수는 실행되지 않고, catch안에있는 콜백함수만 호출되었다.
따라서 저렇게 출력이 나오는거임. 얘는 에러처리할때 쓰게될거다.
+ finally도 있는데
const appointment = new Promise((res, rej) => {
setTimeout(() => {
console.log("프로미스 reject!");
rej("거절!");
}, 1000);
})
.then(() => {
console.log("여기는 then에 있는 콜백함수야");
})
.catch(() => {
console.log("여기는 catch에 있는 콜백함수야");
})
.finally(() => {
console.log("얘는 finally에 있는 콜백함수야");
});
const appointment = new Promise((res, rej) => {
setTimeout(() => {
console.log("프로미스 resolve!");
res("오케이!");
}, 1000);
})
.then(() => {
console.log("여기는 then에 있는 콜백함수야");
})
.catch(() => {
console.log("여기는 catch에 있는 콜백함수야");
})
.finally(() => {
console.log("얘는 finally에 있는 콜백함수야");
});
이렇게 마지막에 reject되든 resolve되든 실행시켜주는 거임.
이걸 세개의 프로미스로 동기처리하면 존재이유를 알 수 있음
# 세 개 함수로 동기처리 테스트 해보기
이런식으로 세가지 promise를 체이닝 해보자~ 여기가 꽃임
const first = () => {
return new Promise((res, rej) => {
setTimeout(() => {
res();
console.log("첫번째 프로미스 끝!");
}, 1000);
});
};
const second = () => {
return new Promise((res, rej) => {
setTimeout(() => {
res();
console.log("두번째 프로미스 끝!");
}, 1000);
});
};
const third = () => {
return new Promise((res, rej) => {
setTimeout(() => {
res();
console.log("세번째 프로미스 끝!");
}, 1000);
});
};
이렇게 promise를 return하는 함수를 세개 만들어줬다. 각 함수에서 return되는 promise는 생성되고 1초후에 resolve로 완료된다
first().then(second).then(third);
졸라게 읽기 쉽게 생겼다.
암튼 출력을 보면?
우리가 원했던대로 1초후에 첫번째 프로미스 끝!
다음 1초후에 두번쨰 끝!
다음 1초후에 세번째 끝!
이렇게 된다.
그림으로 설명하면, 이렇다.
첫번쨰 프로미스는 바로 생기지만 res콜백히 호출되지 않았으므로 pending상태이다. 그리고 1초후에 res콜백이 호출되어 fulfilled상태로 변한다. 이를 확인하고 .then에서 안에있는 second함수를 호출해준다.
이 second함수는 promise를 return하므로 두번째 프로미스가 이 시점에 생성된다. 하지만 아직 res콜백이 호출안됐으므로 pending상태이다. 그리고 1초후에 res콜백이 호출되고 다음 then으로 받고 세번쨰 프로미스를 생성하는 third함수가 호출된다.
이런식으로 동기처리를 할수 있다.
될수있으면 promise를 return하는 함수로 함수를 정의해주면 저렇게 쉽게 쓸 수 있음
# 이제 reject를 araboza
const first = () => {
return new Promise((res, rej) => {
setTimeout(() => {
res();
console.log("첫번째 프로미스 끝!");
}, 1000);
});
};
const second = () => {
return new Promise((res, rej) => {
setTimeout(() => {
rej(); //요기
console.log("두번째 프로미스 끝!");
}, 1000);
});
};
const third = () => {
return new Promise((res, rej) => {
setTimeout(() => {
res();
console.log("세번째 프로미스 끝!");
}, 1000);
});
};
first().then(second).then(third);
이렇게 두번쨰 함수에 resolve대신 reject를 호출했다.
어떻게될까?
첫번쨰 promise는 제대로 실행이 되었다. 1초후에 resolve콜백을 호출해줬고 다음 두번쨰 프로미스로 넘어간다.
근데 얘는 1초후에 reject콜백을 호출한다. 때문에 얘는 에러가 뜨게된다. 당연히 다음 .then인 third프로미스는 생성조차 되지 않게됨.
이걸 처리할수있는게 catch문이다.
const second = () => {
return new Promise((res, rej) => {
setTimeout(() => {
rej("두번쨰는 reject");
console.log("두번째 프로미스 끝!");
}, 1000);
});
};
first()
.then(second)
.then(third)
.catch((err) => {
console.log(err);
});
두번쨰 reject콜백의 인수로 '두번쨰는 reject'라는 스트링을 넣어줬다
출력 결과물을 보면?
아까랑 똑같은데 에러를 띄워주는게 아니라 reject에 인수로 넘겨준 스트링이 출력된다.
catch문에서 rej()콜백에 넣어준 인수데이터를 받은거다.
이건 catch문에서 err파라미터로 해당 스트링을 받았기 때문에 이렇다.
then으로 데이터를 넘겨주는건 아래에서 또 쓸거임.
추가해서 finally까지 추가해주면,
first()
.then(second)
.then(third)
.catch((err) => {
console.log(err);
})
.finally(() => {
console.log("다 끝");
});
마지막에 finally에 있는 콜백함수가 실행된다.
만약 아까 second에 reject한걸 resolve로 고친다면
모든 프로미스가 생성되고 fulfilled되고 마지막에 다 끝이라고 해줌
하지만 finally의 조건은 모든 프로미스 체이닝이 끝난 fulfilled이거나 reject된 상태어야 한다는거다.
const first = () => {
return new Promise((res, rej) => {
setTimeout(() => {
res();
console.log("첫번째 프로미스 끝!");
}, 1000);
});
};
const second = () => {
return new Promise((res, rej) => {
setTimeout(() => {
console.log("두번째 프로미스 끝!");
}, 1000);
});
};
const third = () => {
return new Promise((res, rej) => {
setTimeout(() => {
res();
console.log("세번째 프로미스 끝!");
}, 1000);
});
};
first()
.then(second)
.then(third)
.catch((err) => {
console.log(err);
})
.finally(() => {
console.log("다 끝");
});
두번쨰 프로미스에서 resolve를 없게해서 pending상태로 남게하면
이렇게 아예 finally 콜백함수도 호출이 안된다.
# 프로미스끼리 데이터 넘겨주기
const first = () => {
return new Promise((res, rej) => {
setTimeout(() => {
res("첫번쨰 데이터");
console.log("첫번째 프로미스 끝!");
}, 1000);
});
};
const second = () => {
return new Promise((res, rej) => {
setTimeout(() => {
res("두번쨰 데이터");
console.log("두번째 프로미스 끝!");
}, 1000);
});
};
const third = () => {
return new Promise((res, rej) => {
setTimeout(() => {
res("세번쨰 데이터");
console.log("세번째 프로미스 끝!");
}, 1000);
});
};
first()
.then((data) => {
console.log("두번쨰 promise를 return하는 then");
console.log(data);
return second();
})
.then((data) => {
console.log("세번쨰 promise를 return하는 then");
console.log(data);
return third();
})
.catch((err) => {
console.log(err);
})
.finally(() => {
console.log("다 끝");
});
이 코드를 실행해보면
출력이 이렇게 된다.
코드랑 출력물을 잘 보면, 두번째 promise를 return하는 then이라는 코드 함수 스코프에 있는 console.log(data)에서 첫번째 데이터를 뱉는다.
첫번쨰 프로미스에서 res(data)로 호출해서 넘겨준 data가 다음 .then에 있는 (data)=>{} 함수리터럴에서 data로 받아서 쓸 수 있는거다.
이걸 응용한다면, 우리는 첫번째 promise에서 실행한 코드의 결과값을 res(data)로 다음 체이닝 .then으로 넘겨줄 수 있고,
다음체이닝 함수 호출에 이 데이터를 인수로 넘겨줄 수 있다.
이걸 두개로 더 간단하게 하자면
const first = () => {
return new Promise((res, rej) => {
setTimeout(() => {
res("첫번쨰 데이터");
console.log("첫번째 프로미스 끝!");
}, 1000);
});
};
const second = (dataFromFirstPromise) => {
return new Promise((res, rej) => {
console.log(`let's use ${dataFromFirstPromise} in second promise`);
setTimeout(() => {
res("두번쨰 데이터");
console.log("두번째 프로미스 끝!");
}, 1000);
});
};
first().then((data) => {
return second(data);
});
이렇게 두번째 promise에서 첫번째 promise에서 넘겨준 데이터를 갖다 쓸수 있게 된거다.
나도 이걸 자주 썼는데
예를 들어 db에서 유저정보를 검색한다. 근데 이게 얼마나 오래걸릴지 모르잖음?
그래서 이렇게 promise로 하고 db에서 데이터 찾아올때까지 기다려야함. 이 동안엔 pending상태일테고, 데이터를 받으면 res(유저이름)이런식으로 데이터를 넘겨줬음.
두번째 promise에서는 받은 데이터를 가지고 이 유저에 해당하는 개인정보를 또다시 db에서 찾아야함. 그래서 아까 넘겨받은 데이터를 가지고 또 작업을 하게 한거다. 뭐 사실 join문 쓰면 되는거지만 코드로는 이렇다는거임.
암튼 이런식으로 활용할 수 있다.
+ .then에 들어가는 콜백함수는 어쨋든 호출됨
아까는 그냥 promise를 return해주는 함수리터럴이 참조된 식별자를 바로 넣어줘서 해당 함수가 바로 호출되고 promise를 return해서 다음 .then으로 넘겨준거다.
하지만 이번 예시에서는 데이터를 받아서 출력하기위해 새로운 함수리터럴을 만들어서 그안에 넣어줬기떄문에
first() second() third()로 직접 호출을 해준거다. 그럼 다음 then이 해당 promise를 넘겨받게되어 체이닝이 이뤄질수 있다.
# 정말 정말 중요한점 => then메서드에 인수로 전달하는건 무조껀 promise를 return하는 함수여야 체이닝이 일어난다!
firstPromise().then('여기에 Promise를 return하는 함수리터럴이 들어가야한다.')
우리가 .then으로 프로미스 체이닝을 해봤는데, 이 then메서드에 인수로 전해주는곳엔 무조껀 promise를 return하는 함수리터럴을 인수로 전해줘야한다.
const firstPromise = new Promise(() => {});
const secondPromise = () => {
return new Promise(() => {});
};
//첫번째
firstPromise.then(() => {
return new Promise(() => {});
}); //아예 쌩 promise를 반환하는 함수리터럴을 통쨰로 집어넣거나
//두번쨰
firstPromise.then(secondPromise); // secondPromise라는 식별자엔 프로미스를 return 하는 함수객체가 할당되어있어서 얘도 promise를 return하는 함수리터럴임!
//세번째
firstPromise.then(() => {
return secondPromise();
}); // 함수리터럴에 promise를 return하는 함수를 '호출'해서 반환값을 promise로 전달되게 하거나.
이런식으로 이전 promise에서 넘겨준 데이터를 사용할때는 함수리터럴이 then메서드의 인수로 들어갔는데,
이 리터럴 역시 promise를 반환해야 한다. 때문에 단순히 ()=>{secondPromise(data)}를 써준 게 아니라, return문으로 ()=>{return secondPromise()} promise를 반환하는 secondPromise함수를 '호출'해서 promise를 반환하게한다음 또다시 return해주는 함수리터럴로 작성한것이다. 그래야 다음 promise로 체이닝이 일어날 수 있다.
최대한 간단하게 쓰려해서 resolve를 안했는데 resolve해야 promise가 펜딩 상태에서 fulfilled로 변하니까 이것도 조심하샘.
# 프로미스를 병렬처리 하고싶을떄?
Synchronous Processing & Asynchronous Processing
Introduction예전에 비동기처리를 처음 배울때 너무 이해가안됐다.단순하게 이 함수 실행하고 완료되면 다음 함수 실행되게 하고싶은 내맘을 몰라주는 js였었음.구글링을 해도 큐 스택이니 뭐니 저
jacobowl.tistory.com
이전 동기 비동기 동시 처리 포스팅에서 예시로 썼던 했던 동기+비동기처리 동시에 하는 케이스를 가지고 해보자.
random한 초 후에 무찌를 부르는 함수와 random한 초 후에 도리를 부르는 함수가 두개 동시에 호출되고 어떤 함수가 먼저 끝날지 모르는 상태임. 둘다 무찌랑 도리를 부르게되면 석구를 부르는 함수가 실행되는 플로우를 원하는거임.
비동기+동기 둘다 있는거.
const random = () => {
return Math.floor(Math.random() * 2001);
};
const callMuzzi = () => {
return new Promise((res) => {
setTimeout(() => {
res();
console.log("무찌야!");
}, random());
});
};
const callDori = () => {
return new Promise((res) => {
setTimeout(() => {
res();
console.log("도리야!");
}, random());
});
};
const callSeokgu = () => {
console.log("석구야 ㅠㅠ");
};
Promise.all([callMuzzi(), callDori()]).then(() => {
callSeokgu();
});
코드로 대충 짜봤는데 여기서 새로운 promise의 메서드를 확인 할 수 있다.
Promise객체에 있는 all메서드를 사용할 수 있는데 인수로는 프로미스를 어레이형식으로 받는다.
이 어레이 안에 있는 프로미스들은 비동기적으로 실행되고 모두 fulfilled상태가 되면 then에 있는 함수리터럴을 호출해준다.
훨씬 보기좋고 간단하게 구현할 수 있는거임.
# 병렬처리 promise에서 데이터를 받아오고싶을때?
const random = () => {
return Math.floor(Math.random() * 2001);
};
const callMuzzi = () => {
return new Promise((res) => {
setTimeout(() => {
const dataFromMuzzi = "엉덩이요정 무찌";
res(dataFromMuzzi);
console.log("무찌야!");
}, random());
});
};
const callDori = () => {
return new Promise((res) => {
setTimeout(() => {
const dataFromDori = "도리도리뱅뱅";
res(dataFromDori);
console.log("도리야!");
}, random());
});
};
const callSeokgu = (muzziData, doriData) => {
console.log(`${muzziData}랑 ${doriData}이랑 뛰노는 석구`);
console.log("석구야 ㅠㅠ");
};
Promise.all([callMuzzi(), callDori()]).then(([muzziData, doriData]) => {
callSeokgu(muzziData, doriData);
});
이렇게 두 promise로 resolve로 넘겨주는 then메서드에 어레이 형식 인수로 데이터를 전해줄 수 있다.
출력결과물을 보면 잘 받아온걸 확인가능~
# 괴랄한 실습 해볼까?
ㅋㅋㅋㅋㅋ
const random = () => {
return Math.floor(Math.random() * 2001);
};
function CreateFuc(data) {
this.data = data;
}
CreateFuc.prototype.createFunction = function () {
return (arr) => {
return new Promise((res, rej) => {
setTimeout(() => {
if (typeof arr == "object") {
const flatArr = arr.flat();
flatArr.push(this.data);
res(flatArr);
} else {
res(this.data);
}
}, random());
});
};
};
const fuc1 = new CreateFuc("data1").createFunction();
const fuc2 = new CreateFuc("data2").createFunction();
const fuc3 = new CreateFuc("data3").createFunction();
const fuc4 = new CreateFuc("data4").createFunction();
const fuc5 = new CreateFuc("data5").createFunction();
const fuc6 = new CreateFuc("data6").createFunction();
const top_promise = Promise.all([fuc1(), fuc2()]).then(([data1, data2]) => {
return fuc3([data1, data2]);
});
const bot_promise = fuc4().then((data4) => {
return fuc5([data4]);
});
const final = Promise.all([top_promise, bot_promise])
.then(([data123, data45]) => {
return fuc6([data123, data45]);
})
.then((data) => {
console.log(data);
});
재밋으니 한번 해보세여
const random = () => {
return Math.floor(Math.random() * 2001);
};
function CreateFuc(data) {
this.data = data;
}
CreateFuc.prototype.createFunction = function () {
return (arr) => {
return new Promise((res, rej) => {
setTimeout(() => {
if (typeof arr == "object") {
const flatArr = arr.flat();
flatArr.push(this.data);
res(flatArr);
} else {
res(this.data);
}
}, random());
});
};
};
const fuc1 = new CreateFuc("data1").createFunction();
const fuc2 = new CreateFuc("data2").createFunction();
const fuc3 = new CreateFuc("data3").createFunction();
const fuc4 = new CreateFuc("data4").createFunction();
const fuc5 = new CreateFuc("data5").createFunction();
const fuc6 = new CreateFuc("data6").createFunction();
// 시간 측정 시작
const startTime = performance.now(); // 시작 시간
const top_promise = Promise.all([fuc1(), fuc2()]).then(([data1, data2]) => {
return fuc3([data1, data2]);
});
const bot_promise = fuc4().then((data4) => {
return fuc5([data4]);
});
const final = Promise.all([top_promise, bot_promise])
.then(([data123, data45]) => {
return fuc6([data123, data45]);
})
.then((data) => {
console.log(data);
// 시간 측정 끝
const endTime = performance.now(); // 끝 시간
const elapsedTime = endTime - startTime; // 경과 시간 계산
console.log(`최종적으로 걸린 시간: ${elapsedTime}ms`);
});
gpt한테 걸린시간도 측정하는 코드 짜달랬더니 추가해줬음.
난 걸린시간 코드만 추가해달라고 gpt찬스 쓴거고 promise는 직접 작성했음
공부하려면 직접 짜보세여 gpt찬스 쓰지말고(어차피 요구 제대로 못알아먹음)
+ 이거 한번 생각해보샘
setTimeout(() => {
appointment.then(() => {
console.log("then메서드에 넣은 콜백함수 호출됐어!");
});
}, 0);
const appointment = new Promise((res) => {
setTimeout(() => {
res();
console.log("앙?");
}, 1000);
});
힌트
primitive타입, object타입 mutable(변경가능함)
원시타입은 흔히 우리가 변수에 할당하는 스트링 넘버 등이 있고, 객체타입은 말그대로 객체타입이다. 어레이, 객체, 함수등이 있다. 원시타입과 객체타입은 근본적으로 메모리접근,참조방법에
jacobowl.tistory.com
Conclusion
뭔가 자주썻던건데 포스팅을 하려니 좀 헷갈리는점이 많았따..
솔찍히 포스팅하기 힘들어서 뒷부분은 그림이나 설명이 조금 미흡한듯.
나중에 수정을 하던 뭐하던 해보지뭐.
---
병렬 직렬처리 그림, 괴랄한 함수, promise all데이터 받기 추가완료