Promise의 올바른 사용

Promise를 배우고 좀 사용하다 보면 Promise가 너무 무분별하게 사용되는 건 아닌지, 잘 사용하고 있는지 고민될 때가 있습니다.

composing promise

비동기 프로그래밍 시 callback hell 의 문제를 해결 하기 위해 promise를 사용하는데 promise hell? 처럼 promise를 사용하면서도 pyramid 형식으로 작성하는 것을 피해야 합니다.

// A bad example
promise1()
.then(function(result) {
  promise2()
  .then(function(result) {
    promise3()
    .then(function(result) {
      /* */
    })
    .catch(function(error){
      console.log(error);
    })
  })
});

위의 방식을 아래 방식처럼 표현한 것을 composing promise라 부릅니다.

// A good example
promise1()
.then(function(result) {
  return promise2();
})
.then(function(result) {
  return promise3();
})
.catch(function(error) {
  console.log(error);
});

catch를 항상 사용하자

에러가 발생하지 않는다고 확신해도 catch를 붙이는 습관을 갖도록 합니다.

promise1()
.then(function(result) {
  /* */
})
.catch(function(error) {
  console.log(error);
});

return 을 이용하자

then() 메서드 안에 return 과 throw를 이용합니다. return은 비동기적으로 발생된 값 뿐만 아니라 동기적으로 발생된 값도 전달할 수 있습니다.

promise1().then(function() {
  // return value or undefined
  if(동기적으로 발생한 값을 리턴할 경우)
    return value;
 
  // throw error
  if(에러일 시)
    throw new Error("error");
 
  // return another promise1
    return promise2();
 
});

아래 예제는 return 을 사용하지 않았을 때 p2와 p3 가 동기적으로 실행되지 못한 것을 확인할 수 있습니다. return을 사용하지 않아 p2와 p3가 비동기적으로 실행이 되어 part 2 부분에서 flag 값이 undefined가 출력되었습니다.

var p1 = function() {
  return new Promise(function(resolve, reject) {
    console.log(1);
    resolve(1);
  });
};
 
var p2 = function() {
  return new Promise(function(resolve, reject) {
    console.log(2);
    resolve(2);
  });
};
 
var p3 = function() {
  return new Promise(function(resolve, reject) {
    console.log(3);
    resolve(3);
  });
};
 
var flag = 1;
 
p1()
.then(function(data) {
  // part 1
  flag = data;
  console.log("flag : " + flag);  // flag : 1
  p2();
})
.then(function(data) {
  // part 2
  flag = data;
  console.log("flag : " + flag);  // flag : undefined
  p3();
});

then 은 함수 형태로 전달되어야 한다.

then은 함수 형태로 전달해야 한다는 기억해야 합니다. 아래의 예제에서 result 값으로 bar 가 출력됨을 예상하겠지만 foo 가 출력됩니다. 그 이유는 then() 함수에 함수의 형태가 아닌 것을 전달하기 때문입니다.

Promise.resolve('foo')
.then(Promise.resolve('bar'))
.then(function(result) {
    console.log(result);  // foo
})

아래의 형태로 함수를 then() 메서드로 함수 형태로 promise 를 리턴해야 합니다.

Promise.resolve('foo')
.then(function(result) {
  return Promise.resolve('bar');
})
.then(function(result) {
  console.log(result);
})


'Language > Javascript' 카테고리의 다른 글

다중 플래그값을 위한 비트 연산  (0) 2017.12.30
Name Spacing Pattern  (0) 2017.07.28
promise - 1 [then, catch, resolve, reject]  (0) 2017.07.28
closure  (0) 2017.07.28
scope - 3 [변수 숨기기]  (0) 2017.07.28

+ Recent posts