what is Promise? 4. error note

zenibako.lee
4 min readOct 19, 2019

--

프로미스 비동기 처리 에러 처리 기록 Promise.resolve()

 asyncMap([  function(cb){    setTimeout(function(){      cb('one');    }, 200);  },  function(cb){    setTimeout(function(){      cb('two');    }, 100);  } ],  function(results){    // the results array will equal ['one','two'] even though    // the second function had a shorter timeout.    console.log(results); // ['one', 'two'] });

셋타임아웃으로 callback을 실행하는 함수들의 array를 첫 번 째 인자로 받고,

두번째 인자로 array 내 모든 함수를 실행 후 return array를 대상으로 실행하는 callback함수를 받는다.

(함수array가 setTimeout의 callback으로 실행하는 함수와 asyncMap의 함수의 callback은 다르다)

이러한 기능을 하기 위해 처음 만들어본 코드는

아래와 같다.

var asyncMap = function(tasks, callback){return Promise.all(tasks.map(func => new Promise(function(resolve,rejct){resolve(func((a)=>{console.log('a',a); return(a)}))}))).then((result)=>{console.log('all result',result);callback(result)});};

계속 에러가 발생했다.

promise.all내에 setTimeout 콜백이 호출 되기도 전에,

then의 all result로 undefined가 전달이 되고, 그 이후 setTimeout콜백의 동작을 확인할 수 있었다.

=> 비동기처리가 안되고 있다.

문제가 뭘까 생각하며 이것저것 여러가지 형태를 바꿔가며 조작해 보았다.

(이해가 부족한 탓)

결국 찾은 정답은

map 내부의 resolve와 내부 return의 위치를 바꿔주는 것이었다.

var asyncMap = function(tasks, callback){return Promise.all(tasks.map(func => new Promise(function(resolve,rejct){return(    //이곳과func((a)=>{console.log('a',a); resolve(a)})  //이곳을 바꿔주었다.)}))).then((result)=>{console.log('all result',result);callback(result)});};

생각해볼 수 있는 오류의 원인은 두가지 였다.

  1. map이후 return 으로 최종 값까지 가서,

최종적으로 resolve를 해줘야, map이 정상 작동한다.

2. map의 실행과 상관없이, Promise 생성자를 return하는 경우,

resolve는 최종 return에 사용해야 한다.

궁금해서 Promise.resolve()에 대해 찾아보았다.

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/resolve

Promise 객체의 메소드인 resolve는,

느낌상 return + promise status to resolved의 기능을 갖는걸로 생각했다.

그러나 return과 다른 점이 존재한다.

resolve는 해당 Promise이 resolve가 되는 것이 먼저이고, 그 후 resolve의 결과를 return한다.

따라서 기존에 오류가 났던 코드를 보면,

resolve(func((a)=>{console.log('a',a); return(a)}))

이와 같다.

이전까지 정의한 promise의 상태가 resolve가 되고, 그결과로 나온 값이 들어가야 할 resolve()내부에, 함수실행이 들어가고, 그 결과,

promise.all의 결과로, 그저 func() === settimeout펑션의 호출을 return하고 있을 뿐이었다.

결론적으로 가정했던 오류의 원인들 중 2번째,

2. map의 실행과 상관없이, Promise 생성자를 return하는 경우,resolve는 최종 return에 사용해야 한다.

라는 부분을 놓쳐서 생긴 에러로 생각 할 수 있다.

--

--

zenibako.lee
zenibako.lee

Written by zenibako.lee

backend engineer, JS, Node, AWS

No responses yet