[JS] new Promise 사용해보기

준리·2022년 9월 23일
0

비동기 프로그래밍

목록 보기
3/10
post-thumbnail

이전 프로미스 개념글 참고
[JS] promise, 비동기프로그래밍 진짜 이해함 ? 쉽다쉬워 : 열받네

프라미스를 설명으로 이해하기 링크

Promise는 프로미스가 생성된 시점에는 알려지지 않았을 수도 있는 값을 위한 대리자로, 비동기 연산이 종료된 이후에 결과 값과 실패 사유를 처리하기 위한 처리기를 연결할 수 있습니다. 프로미스를 사용하면 비동기 메서드에서 마치 동기 메서드처럼 값을 반환할 수 있습니다. 다만 최종 결과를 반환하는 것이 아니고, 미래의 어떤 시점에 결과를 제공하겠다는 '약속'(프로미스)을 반환합니다.


#1 다음 코드를 Promise를 이용하여 refactoring 하시오.

//앞에서 작성한 다음 코드를 Promise를 이용하여 refactoring 하시오.

setTimeout(function () {
    console.log("depth1", new Date());
    setTimeout(function () {
        console.log("depth2", new Date());
        setTimeout(function () {
            console.log("depth3", new Date());
            throw new Error("Already 3-depth!!");
        }, 3000);
    }, 2000);
}, 1000);

console.log("START!", new Date());
/*
START! 2022-09-22T07:16:50.765Z
depth1 2022-09-22T07:16:51.770Z
depth2 2022-09-22T07:16:53.776Z
depth3 2022-09-22T07:16:56.780Z
file:///E:/AI/220702%20fullstack/jsbasic/0917/vv_promise.js:9
            throw new Error("Already 3-depth!!");
            ^

Error: Already 3-depth!!
*/

💫callback patten ⇒ Promise

const iPromise = (depth) => {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            if (depth >= 3) reject(new Error("Already 3-depth!!"));
            console.log(`depth${depth}`, new Date());
            resolve(depth + 1);
        }, depth * 1000);
    });
};

iPromise(1).then(iPromise).then(iPromise).then(iPromise);

console.log("START!", new Date());

iPromise 함수를 만든다.
매개변수로 depth를 받는다. 이 함수는 Promise를 return 해줄 것이다.
return 에 new Promise 를 선언하고 습관적으로 resolve 와 reject를 매개변수로 받는다.
setTimeout을 통해 시간 delay를 줄 것이다.
setTimeout을 오픈한다. reject를 먼저 사용해 줄건데 만약 depth가 3이상일 때 reject를 리턴한다. 에러 메세지를 담아 보낸다. 에러처리를 먼저해주는 것이 불필요한 리소스 소비를 막을 수 있다.

3이하라면 예정대로 콘솔을 실행하고 resolve에 depth를 + 1 해주고 보내준다.

iPromise(1).then(iPromise).then(iPromise).then(iPromise);
해당 함수는 Promise를 return 하기때문에 then와 catch, finally를 가질 수 있다. 따라서 위의 then에는 resolve값인 2가 들어오고 추가적으로 1개가 늘려가게 된다. 4번째 then 소환 시 error가 나게 된다.

#2 테스트를 위한 임의의 시간(1초 미만)에 resolve를 실행하는 randTime 함수를 작성하시오.

//테스트를 위한 임의의 시간(1초 미만)에 resolve를 실행하는 randTime 함수를 작성하시오.
const randTime = val => {
}

[1, 2, 3, 4, 5].forEach(a => randTime(a).then(console.log));

문제를 이해하는 것 자체가 어렵다. [...] 배열을 forEach로 돌려 randTime에 인자로 집어 넣는다. 그리고 randTime 함수는 1초미만의 값을 뱉어내는 delay 변수를 가지고 있다. 그 생성된 시간별로 value값을 출력해준다는 내용이다.
이는 실제 비동기를 실행하는 것과 비슷한 효과가 나타날 수 있다. API가 먼저 뭐가 올지 모르니까 말이다.

문제를 이해하지 못하고 삽질한 버전

const arr = [];
const randTime = (val) => {
    return new Promise((resolve, reject) => {
        const delay = Math.floor(Math.random() * 1000);
        console.log("val num :>> ", val, num);
     	arr.push(delay)
        if (arr.length >= 5) arr.sort((a, b) => a - b);
        resolve();
    });
};

delay값을 arr로 때려 박아서 그 인덱스를 가지고 어떻게 해보려고 했는데, 전혀 다른 접근이었다 ^^!

💫callback patten ⇒ Promise

//테스트를 위한 임의의 시간(1초 미만)에 resolve를 실행하는 randTime 함수를 작성하시오.
const randTime = (val) => {
    return new Promise((resolve) => {
        const delay = Math.random() * 1000;
        console.log(val, delay);
        setTimeout(resolve, delay, val);
      
      	// 위와 같은 거 
        // setTimeout(() => {
        //     resolve(val);
        // }, delay);
    });
};

[1, 2, 3, 4, 5].forEach((a) => randTime(a).then(console.log));

결론

Promise는 resolve와 reject 함수를 매개변수로 가진 함수이다. 이들은 콜백함수인데, 이를 인지한 것만으로도 엄청난 성과이다. 반드시 미래에 성공과 실패라는 두 가지 결과를 가져온다. 싱글스레드지만 병렬적인 작업을 하고 있다는 것도 알 수 있다. 앞에 공부해본 브라우저의 역할이 있어서이다. 실제로 프로미스 함수를 만들어보며, 그 내부를 까봐야겠다.

출처

SSAC 영등포 교육기관에서 풀스택 실무 프로젝트 과정을 수강하고 있다. JS전반을 깊이 있게 배우고 실무에 사용되는 프로젝트를 다룬다. 앞으로 그 과정 중의 내용을 블로그에 다루고자 한다.

profile
트렌디 풀스택 개발자

0개의 댓글