위의 코드에서 `.exe()` 메서드를 사용하여 `query`를 프로미스로 변환하고, `.then()` 및 `.catch()`를 사용하여 비동기 쿼리 작업을 처리합니다.
#`.exec()` vs `.then()`
Mongoose쿼리는 `.then()` 함수를 지원하므로 "thenable"이라고 할 수 있습니다 .이것은 `.exec()`를 사용하지 않고도 `.then()`을 직접 호출하여 쿼리를 처리할 수 있음을 의미합니다. 그러나 `.then()`함수만으로는 일반적인 프로미스의 모든 기능을 제공받을 수 없습니다.
위의 코드에서 `query`는 `thenable`이기 때문에 `.then()`을 사용할 수 있지만, `catch()` 및 기타 프로미스 메서드를 직접 사용할 수 없습니다.
# `exe()` 와 `async/await`
Mongoose 쿼리는 ` async/await`와 함께 사용하기에 이상적입니다. `.exec()`를 사용하면 `async/await`를 통해 코드를 더 간결하게 작성할 수 있습니다.
예를 들어
const result = await Model.findOne({ name: 'Neo' }).exec();
console.log(result);
`.exec()`를 사용하면 스택 추적(stack trace)이 더 자세하게 표시되므로 디버깅에 유용합니다.
요약하면, `.exec()` 메서드는 Mongoose 쿼리를 프로미스로 변환하여 비동기 작업을 처리하는데 사용됩니다. 이를 통해 코드를 보다 간결하게 작성하고, 프로미스 기능을 활용하여 비동기 작업을 처리할 수 있습니다.
# 핵심of핵심
1. Mongoose5 이후 부터 비동기 작업이 암시적으로 프로미스를 반환합니다. `.save()' 혹은 `find().exec()`를 사용하여 비동기 코드를 작성할 수 있습니다.
2. Mongoose 쿼리는 프로미스가 아닙니다. 그러나 `. then()` 함수를 사용하여 비슷한 기능을 사용할 수 있습니다. 만약 '.exec()'를 사용하면 쿼리를 프로미스로 변환할 수 있습니다.
3. 쿼리는 thenable 쿼리는 프로미스가 아니지만 `.then()` 함수를 가지고 있어서 Promise Chaining 또는 async/await를 통해 쿼리를 프로미스처럼 사용할 수 있습니다. 'exec()'를 사용하면 추가적인 프로미스 메서드를 사용할 수 있스며, 스택 추적이 더 자세하게 표시됩니다.
4. async/await 사용 Mongoose 쿼리는 async/await와 함께 사용하기에 이상적입니다. '.exec()'를 사용하면 async/await를 통해 간결한 코드를 작성하고 디버깅을 용이하게 할 수 있습니다.
# 실제로 적용해보자
실제로 적용한 코드의 일부분을 긁어와서 설명드리겠습니다.
1) `await Todo.findOne().sort('-order').exec()`
데이터베이베이스에서 'order' 값을 기준으로 내림차순으로 정렬된 첫 번째 항목을 찾습니다. 이를 통해 데이터베이스에 저장된 메모 중에서 가장 높은 'order'값을 가져옵니다. `.exec()`를 사용하여 이 작업을 프로미스로 처리하고 `maxOrderByUserId` 변수에 할당합니다.
2) 'order' 값 계산
'maxOrderByUserId'를 확인하여 'order' 값을 계산합니다. 만약 'maxOrderByUserId'가 있으면 그 값에 1을 더하여 'order' 값을 설정하고, 그렇지 않으면 1로 설정합니다.
3) 새로운 'Todo' 모델 생성
'value'와 계산된 'order' 값을 사용하여 새로운 ' Todo' 모델을 만듭니다.
4) ` await todo.save()`
새로운 'Todo' 모델을 데이터베이스에 저장합니다. 이 작업 역시 비동기로 처리되며, `await`를 사용하여 데이터베이스 작업이 완료될 때까지 대기합니다.
5) 'todo' 객체 반환
저장된 메모 정보를 JSON 형식으로 응답으로 반환합니다.
=> 이런한 방식으로 코드는 Mongoose의 프로미스 지원과 `await`/ `async`를 사용하여 비동기 작업을 처리합니다. Mongoose는 `.save()` 및 `.exec()` 와 같은 비동기 작업에서 내장 프로미스를 사용합니다.