알아두면 유용한 Javascript Promise 활용 팁

Q&A 큐레이션

1. JS promise 이름은 왜 promise인가요?

안녕하세요~ 자바스크립트의 promise는 왜 promise라는 이름이 지어진건가요?? 구글링해도 잘 못찾겠네요.


답변

그렇게 깊이 생각해본 적 없는 뇌피셜입니다만, 전 그냥 단순하게 직역해서 "약속"이라고 이해했습니다. "네가 요청한 걸 해줄게"라는 약속인 건데, 이게 언제될지, 정말 꼭 지켜질지 모르는 상태인 거죠. 약속이 안 지켜질 수도 있다는 점에서 실패할 수도 있는 것과 마찬가지고요. 약속 자체는, 약속의 실행 결과물이 아니라는 점도 비슷합니다. 내가 너에게 500원을 갚을게라는 약속은 500원이 아닙니다. 약속이 이행됐을 때, 500원이 있거나 없거나 하겠죠. 당장 이뤄지지 않을 일이나 오래 걸리는 일도, 약속 자체는 미리 받을 수가 있습니다. 다음 달까지 500원 갚는다고 약속했다고 할 때, 500원은 아직 없지만, 약속을 믿고 어느 정도 나름의 경제 활동(?)을 지금 당장부터 다음 달까지 계획하고 진행할 수 있겠습니다. 500원이 없는 상태에서도 말이죠! 자바스크립트 환경에서는, 비동기 처리를 Promise로 감싸서 처리하는 걸로 알고 있는데요, 어떤 행위를 요청해서 약속을 받아내고, 그 결과를 어떻게할지, Promise를 통해서 처리하는 식이죠. 약속만 미리 받아 놓고, 그 약속이 (나중에) 이행되고 나면 뭘할지 선제 대응해둘 수 있겠습니다. 다른 언어 환경에서는 Future/Promise라고 쓰는 경우도 있는데, 제한적 역할이나 이름만 다를 뿐, 사용하는 취지는 비슷한 것 같습니다. 이번에도 꽤 추상적인 답변인 것 같은데요, 구체적인 정보는 앞서 손정현님이 남겨주신 좋은 내용 참고하시면 좋을 것 같습니다.

외 1개 답변 보러 가기

2. 자바스크립트 promise관련 질문입니다

Producing code와 consuming code가 나눠져있음의 장점이 Producing code가 선언되어있다면 언제나 consuming code로 원하는 순서에 실행할 수 있다 맞나요


답변

해당 질문에는 await와 async의 대한 지식이 포함된 질문이 아닙니다. https://developer.mozilla.org/ko/docs/Web/JavaScript/Guide/Using_promises 이 글로 참고하세요. 또한 Promise를 써야 하는 이유부터 접근 하셔야 합니다. ex) 첫번째 비동기 통신으로 받은 return값을 두번째 비동기 통신의 매개변수로 사용해야 한다. 그런데 첫번째 비동기 통신보다 두번째 비동기 통신이 먼저 들어온다면???

이 질문 바로 가기

3. Promise.all과 Promise.allSettled 차이

최근 회사에 입사해서 여러 코드를 보고 있는데 Promise.all과 Promise.allSettled를 많이 사용하고 있더라고요. 두 method가 구별되어서 사용되지는 않고 있는데 크게 문제는 없습니다. 검색해보니 Promise.all은 하나만 실패해도 결과를 얻을 수 없고, Promise.allSettled는 전부 결과를 얻을 수 있다고 하네요. 각각을 어떤기준을 가지고 현업에서 사용하는지 알고싶습니다.


답변

Promise.all과 Promise.allSettled는 비슷하게 사용되지만 사용되는 방식은 다릅니다. 일단 두 메서드의 공통점이 있습니다. 먼저 동시에 Promise들을 처리할 수 있습니다. 예를들어 API요청이라고 하면 각각의 결과를 얻기위해 다음처럼 순차적으로 요청하는 경우가 많습니다 const resultA = await requestA const resultB = await requestB const resultC = await requestC 하지만 Promise.all과 Promise.allSettled를 사용하면 세 가지를 동시에 요청하고 결과를 얻을 수 있습니다. 하지만 두 메서드의 차이점이 있습니다. 일단 결과의 형태에 차이가 있습니다. promise.all같은 경우 성공한 결과값을 배열형태로 가지고 있습니다. Promise.allSettled는 각각의 결과값도 물론 가지고 있고 요청한 status도 가지고 있습니다. 형태로 보면 promise.all은 [1, 2, 3]이고 Promise.allSettled는 [{ status: 'fulfilled', value: 1}, { status: 'fulfilled', value: 2}, { status: 'fulfilled', value: 3}] 이 됩니다. 결과값을 사용할때의 처리가 조금 달라지게 되겠죠? 그리고 큰 차이점 중 하나는 요청이 실패할 때 나타납니다. 모든 요청이 성공한다면 (reject가 없음) 모든 결과를 얻을 수 있지만 요청이 하나라도 실패한다면 두 메서드는 완전하게 달라집니다. Promise.all같은 경우는 1개만 reject가 되더라도 다른 요청의 결과와 관계없이 결과값은 reject입니다. 하지만 Promise.allSettled는 각각의 요청이 fulfilled인지 rejected인지 나오게 됩니다. 각각의 fulfilled/rejected에 따라 데이터를 처리할 수 있습니다. 그래서 Promise.all은 서로 의존성이 있는 데이터를 가져올 때 사용합니다. API를 요청해서 여러 데이터를 조합해야할 때 1개만 실패해도 사용자에게 보여 줄 수 없을 때 사용합니다. 반대로 Promise.allSettled는 feature가 다를 때 주로 사용하는 것 같습니다. A,B,C의 데이터를 가져왔을 때 데이터가 일부 없어도 각각 사용할 수 있다면 사용합니다. 사실 개발하다보면 에러처리를 많이 생각하지 않을때가 있습니다. 로컬에서 사용하는 API는 항상 success고 억지로 request fail을 내지않는다면 잘 발생하지 않기때문에 두 가지를 혼용해서 사용하는 경우가 많은데요. 에러처리와 데이터가 사용되는 역할에 따라서 해당 메서드들을 잘 사용하는 것도 개발자에게 필요한 역량이지 않을까 싶습니다! 화이팅!

이 질문 바로 가기

4. Promise.all 에 실행 순서를 보장할 수 있는 방법이 있나요?

안녕하세요! Javascript Promise.all에서 실행 순서를 보장할 수 있는 방법이 있는지 궁금합니다! 추가적으로 Promise.all에서 돌아가는 함수들의 실행 시간을 설정할 수 있는지도 궁금합니다~


답변

안녕하세요! Promise.all의 함수 호출 실행 순서를 말씀하시는 것인가요? 그렇다면 보장되는 것으로 알고 있습니다. 이유는 Promise.all (https://tc39.es/ecma262/#sec-promise.all-resolve-element-functions)을 실행시키는 PerformPromiseAll (https://tc39.es/ecma262/#sec-performpromiseall)을 보시면 단순히 반복문을 돌면서 각 함수를 실행시키기 때문입니다. 결과 값도 Promise.all에 제공한 배열의 순서대로 반환해줍니다. 하지만, 어떤 비동기 함수가 먼저 처리 (resolve)될지는 알 수 없습니다. 실행 시간을 설정해야한다면 Promise.race와 setTimeout으로 구현할 수 있는 것 같습니다. https://advancedweb.hu/how-to-add-timeout-to-a-promise-in-javascript/ 이 블로그에 상세히 나와있어요 :)

외 1개 답변 보러 가기

5. aws lambda에서 nodejs promise 비동기 호출하는 방법

안녕하세요~ node.js 14를 aws lambda로 구동시켜서 작업 중에 있는데요. 배치 작업을 하나 만들었는데, 코드 중에 비동기로 다른 서비스를 호출해도 되는 요청이 있어서 await을 걸지 않았는데 로그를 보니 해당 코드가 요청하기 전에 람다가 꺼지는 것 같아서요. 혹시 이유를 아시는분 계신가요?


답변

AWS Lambda 생명주기로 Invoke 시점에 handler가 실행되는데, 해당 함수가 종료되면, (추가로 지금 처리해야 할 이벤트가 없는 경우) 해당 런타임은 종료될 수 있습니다. 그러니, 위 handler()함수가 빠져나가고 나면, 비동기 호출을 해놓은 것이 실행 완료되기 전에 런타임이 종료될 상황인 거네요. 간단하게는, await를 걸어서 비동기 호출 종료시까지 대기하면 될 텐데요, 아마 해당 람다 함수를 HTTP API용도 등으로 사용하고 있어서, 빠른 응답을 돌려주고 빠지시려는 것 같습니다. 질문자님 덕분에, 저도 이렇게 비동기 작업을 추가로 할 경우 어떻게 해야할까 찾아봤습니다. 당장 성패 응답을 주고 비동기로 뭔가 추가 작업을 하려면, https://docs.aws.amazon.com/lambda/latest/dg/invocation-async.html 여기 문서를 참고해서, 비동기 요청을 남기고 빠지면 될 것 같습니다. 기본적으로는 SQS등에 처리할 작업을 위임해 놓고 빠지는 거라고 보면 될 것 같네요. 해당 작업을 추가 처리하는 Lambda를 따로 두거나 하는 식으로 위임받은 일을 처리하면 될 것 같네요. 위 문서는 위 작업을 정형화 해둔 것 같습니다.

외 1개 답변 보러 가기

6. 비동기 함수 return 값은 뭔가요?

const asyncFunction = async () => {return 1} console.log(asyncFunction()) 이 경우 1이 나오지 않습니다. 비동기함수 어렵네요...


답변

비동기 함수의 return 값은 Promise를 반환합니다. 위의 const asyncFunction = async () => {return 1}는 const asyncFunction =() => Promise.resolve(1)과 같은 코드입니다. 1이 나오게 하려면 await을 사용해주면 됩니다. const asyncFunction = async () => {return 1} const result = await asyncFunction() console.log(result)

이 질문 바로 가기

지금 가입하면 모든 질문의 답변을 볼 수 있어요!

현직자들의 명쾌한 답변을 얻을 수 있어요.

또는

이미 회원이신가요?

실무, 커리어 고민이 있다면

새로운 질문 올리기

지금 가입하면 모든 질문의 답변을 볼 수 있어요!