JS로 개발하다 보면 비동기 처리에 항상 신경을 쓸 수밖에 없습니다.
만약 얼마나 걸릴지 알수없는 함수 가 있고 그 함수를 호출해야 하는 함수는 오래 걸리는 메서드의 프로세스가 끝난 뒤에 결과 값을 출력해야 하는 경우라면 어떻게 해야 할까요?
1const RandomTimeSec = parseInt(Math.random() * 10);
2
3const longTimeFunc = () => {
4 setTimeout(() => {
5 console.log(RandomTimeSec + "초만큼 걸렸네요");
6 }, RandomTimeSec * 1000);
7};
8
9const originalFunc = () => {
10 longTimeFunc();
11 console.log("originalFunc 끝났습니다.");
12};
13
14originalFunc();
1//result
2originalFunc 끝났습니다.
36초만큼 걸렸네요
originalFunc 끝났습니다가 나중에 찍혀야 한다면..
Callback
1const RandomTimeSec = parseInt(Math.random() * 10);
2
3const longTimeFunc = (callback) => {
4 setTimeout(() => {
5 console.log(RandomTimeSec + "초만큼 걸렸네요");
6 callback();
7 }, RandomTimeSec * 1000);
8};
9
10const originalFunc = () => {
11 const printResult = () => {
12 console.log("originalFunc 끝났습니다.");
13 };
14 longTimeFunc(printResult);
15};
16
17originalFunc();
16초만큼 걸렸네요
2originalFunc 끝났습니다.
가장 Basic 한 방법입니다.
나중에 실행해야 하는 로직을 함수에 담아 보내고 longTimeFunc이 다 끝나면 해당 함수를 실행시킵니다.
다만, callback함수를 쓰는 것은 실행해야 할 함수가 많아지면 어떤 게 어떤 함수의 callback 인지 헷갈리는 경우가 있기 때문에 가독성이 떨어집니다.
을 사용하는 방법도 다양합니다. , 를 사용할 수도 있습니다.
1/*new Promise 사용하기*/
2const RandomTimeSec = parseInt(Math.random() * 10);
3
4const longTimeFunc = (callback) => {
5 setTimeout(() => {
6 console.log(RandomTimeSec + "초만큼 걸렸네요");
7 callback();
8 }, RandomTimeSec * 1000);
9};
10
11const originalFunc = () => {
12 console.log("originalFunc 끝났습니다.");
13};
14
15new Promise((resolve) => {
16 longTimeFunc(resolve);
17}).then(() => {
18 originalFunc();
19});
13초만큼 걸렸네요
2originalFunc 끝났습니다.
new Promise then을 사용하면 로직자체가 한눈에 들어옵니다. 하지만 더 한눈에 들어오게 하는 방법이 있습니다.
1/*async await 사용하기 */
2const RandomTimeSec = parseInt(Math.random() * 10);
3
4const longTimeFunc = () => {
5 return new Promise((resolve) => {
6 setTimeout(() => {
7 console.log(RandomTimeSec + "초만큼 걸렸네요");
8 resolve();
9 }, RandomTimeSec * 1000);
10 });
11};
12const originalFunc = async () => {
13 await longTimeFunc();
14 console.log("originalFunc 끝났습니다.");
15};
16
17originalFunc();
를 쓰면 await이라는 단어 때문인지 어떤 함수를 기다리고 어떤 절차로 진행되는지 파악하기가 더 쉬워집니다.
new Promise 안에 는 한 가지 비밀이 있는데 다음 실행해야 할 함수에 첫 번째 파라미터만 전달할 수 있습니다.
1const RandomTimeSec = parseInt(Math.random() * 10);
2
3const longTimeFunc = () => {
4 return new Promise((resolve) => {
5 setTimeout(() => {
6 console.log(RandomTimeSec + "초만큼 걸렸네요");
7 resolve(1, 2);
8 }, RandomTimeSec * 1000);
9 });
10};
11const originalFunc = async () => {
12 let result = await longTimeFunc();
13 console.log(result);
14};
15
16originalFunc();
만약 longTimeFunc에서 여러 개의 값을 return
해야 하는 상황이 온다면 배열에 담거나 object에 담아 resolve로 보내야 합니다.
1/*async await 사용하기 */
2const RandomTimeSec = parseInt(Math.random() * 10);
3
4const longTimeFunc = () => {
5 return new Promise((resolve) => {
6 setTimeout(() => {
7 console.log(RandomTimeSec + "초만큼 걸렸네요");
8 resolve({ first: 1, second: 2 });
9 }, RandomTimeSec * 1000);
10 });
11};
12const originalFunc = async () => {
13 let result = await longTimeFunc();
14 console.log(result);
15};
16
17originalFunc();
12초만큼 걸렸네요
2{ first: 1, second: 2 }
여러 가지 방법이 있지만 혼자만 개발하는 것이 아니니 최대한 다른 사람이 보기에도 한 눈에 읽히는 코드를 짜야하는걸 매번 느낍니다. 더 한 코드를 짜는 날까지!