200611 TIL :: Promise

2020. 6. 9. 19:26JavaScript

## try catch와 throw

 

try 블록 안에는 성공적으로 실행되었을 때를 포함해서, 일반적으로 실행되는 경우의 코드들이 들어 있다.

try 블록 안에서 에러가 발생했을 경우에는 코드의 흐름이 catch문으로 넘어가게 된다.

 

try 블록 안쪽에서 에러 처리를 해 줘야 겠다! 라고 생각되는 부분에 throw 문을 이용해서 임의로 에러를 발생시킨다. (커스텀 에러를 만든다?)

 

그러면 try 블록을 타고 내려오다가 throw를 만나면, 코드는 남은 try문을 쭉 실행하는 것이 아니라 catch문으로 바로 들어가 에러 처리를 해 준다. (코드의 흐름이 바뀐다)

 

const getReq = function (url, callback) {
  try {
    http
      .get(url, function (res) {
        ...
        });
        res.on("end", () => {
          ...
        });
      })
      .on("error", (e) => {
        callback(e, null);
      });
  } catch (err) {
    callback(err, null);
  }
};

 

과제를 진행하며 위의 코드에서 on 메소드의 error 이벤트로 에러를 잡아주었다고 생각했는데, 굳이 try - catch 문으로 감싸준 이유가 궁금했었다.

 

get의 on('error') 이벤트로 에러를 잡아주긴 하지만, 모든 에러를 처리해주지는 못한다. 여기서 미처 잡아주지 못하는 에러가 발생하기 때문에 꼭 try - catch로 감싼 뒤, catch문에서 에러를 잡아줘야 한다.

불가피한 상황에서 멈추지 않는 프로그램을 만들 때 try - catch를 사용하고, 에러 잡는 부분을 둘다 작성하는 이유는 모든 경우의 에러를 잡아 주기 위함이다.

 

참고:

https://github.com/node-fetch/node-fetch

 

 

 

## promise chaining에서 then을 통해 return 값이 타고 들어가는 그림이 잘 잡히지 않았다.

 

이미 알고 있었던 것은: 

then의 첫번째 인자로 들어오는 값은 promise가 fulfilled 되었을 때 반환하는 결과값이고, 그 결과값은 promise-then들이 잇고 있는 promise chain 바깥에서는 접근할 수 없는 값이라는 것은 알고 있었다.

 

참고:

https://stackoverflow.com/questions/14220321/how-do-i-return-the-response-from-an-asynchronous-call

https://stackoverflow.com/questions/43422932/async-await-always-returns-promise

 

그런데 아래와 같은 경우에는 결과값들이 then - return을 타고 어떻게 전해질 수 있는지가 헷갈렸다.

// func는 promise를 리턴하는 함수
// arg1, arg2는 func의 실행에 필요한 인자
// asyncArrayMaker는 func에서 받아온 number 형태의 값들을 string 형태의 배열로 리턴하는 함수

const asyncArrayMaker = () => {
  return func(arg1)
    .then(number1 => {
      return func(arg2).then(number2 => {
        return [number1, number2];
      });
    })
    .then(array => array.map(element => toString(element)));
};

 

처음에 했던 생각:

2번째 줄에서 return func를 해 주면 결과값으로 promise를 반환받을 것이라고 생각했다.

8번째 줄의 마지막 then에서 받는 결과값이 혹시 위에서 두 번의 then을 거치고 난 그 promise가 아닐까?

그래서 array에는 두 번의 func를 거친 promise가 들어오게 되고, 그 promise가 fulfilled 되었을 때의 결과값은 결국 [number1, number2] 가 되니까 마지막 then의 array에 [number1, number2] 가 들어오게 되는 것은 아닐까..?

 

조금 더 공부하고 이해한 내용:

위의 예시에는 비동기 호출이 2번 들어가게 되고, 마지막 return에서는 비동기 호출이 끝나서 그 return 값을 결과로 하는 promise를 반환하게 된다고 한다. (원래 했던 생각이 어느정도 방향은 맞았던 것 같다)

 

4번째 줄의 두번째 return에서 promise 자체를 return시키고 있는데, 그 부분이 중요하다.

return을 해주지 않는다면, 8번째 줄의 then에서 값을 받을 수가 없게 된다.

return이 없으면 return값이 아예 없기 때문에 아무 값도 넘겨주지 않게 되고, return을 해 준다면 promise 자체를 return시키게 된다.

8번째 줄의 then에서는 위에서 retrun받은 promise가 fulfilled되었을 때의 결과값을 첫번째 인자로 받게 된다.

 

추가적으로, promise 패턴에서는 다음번 then의 첫번째 인자로 어떤 값이 들어가게 하는지가 중요하고,

then은 비동기/동기 어느 쪽을 리턴해도 다음번 then에서 받을 수 있다.

 

 

 

## Promise.all

Promise.all에서는 인자로 받은 배열의 promise들이 한번에 실행된다. 결과의 반환은 가장 늦게 끝나는 promise까지 다 fulfill된 후에 이루어지게 된다.

반면 promise chaining / async, await에서는 promise가 순차적으로 실행된다. (하나 fulfill되면 다음 promise 실행..)

 

promise.all에서 catch로 에러 잡을 때: 인자로 받은 배열의 promise들 중 하나라도 실패하면 catch문으로 넘어가게 된다.

 ->  그래서 나온 것이 Promise.allSetteled :  reject되었을 경우에도 모든 결과값을 반환해준다.

 

참고:

https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Promise/all

https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Promise/allSettled

 

 

 

 

'JavaScript' 카테고리의 다른 글

ES6 class, super  (0) 2020.05.08
Object Oriented Programming  (0) 2020.05.08
Closure  (0) 2020.04.28
이벤트 버블링과 캡쳐  (0) 2020.03.26
function method, this  (0) 2020.03.18