ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • # TIL_mongoose에서의 Promise??_exec()
    TIL (Today I Learned) 2023. 11. 7. 21:20

    # 몽고수의 길_(밑에 핵심있습니다. 시간을 아끼세요!)

    Mongoose에서 `.exec()` 메서드를 사용하면 Mongoose 쿼리를 프로미스로 변환하여 비동기 작업을 처리하는데 도움을 줍니다. `exec()`를 사용하면 Mongoose의 비동기 작업을 더 효과적으로 처리할 수 있습니다. 

    # Mongoose의 Promises 지원 

    Mongoose5 버전부터, Mongoose는 내장된 프로미스를 지원합니다. 이것은 `.save()` 및 `find().exec()`와 같은 Mongoose의 비동기 작업은 암시적으로 프로미스를 반환합니다. 

    const Model = mongoose.model('Test', Schema({
      name: String
    }));
    
    const doc = new Model({ name: 'Neo' });
    
    const promise = doc.save(); // .save() 메서드는 프로미스를 반환함
    promise instanceof Promise; // true

    `.save()` 메서드는 프로미스를 반환하므로 `promise.then()` 또는 `await promise`와 같은 프로미스 기능을 사용하여 비동기 작업을 처리할 수 있습니다. 

     

    # `.exec()`을 사용한 쿼리 

    Mongoose 쿼리 객체는 `.exe()` 메서드를 사용하여 쿼리 결과를 프로미스로 변환할 수 있습니다. 이것은 쿼리 결과 `.then()` 또는 `async/await`와 함께 처리하기 위해 사용됩니다. 

    const query = Model.find({ name: 'Neo' });
    
    query.exec()
      .then(function (result) {
        console.log(result);
      })
      .catch(function (error) {
        console.error(error);
      });

    위의 코드에서 `.exe()` 메서드를 사용하여 `query`를 프로미스로 변환하고, `.then()` 및 `.catch()`를 사용하여  비동기 쿼리 작업을 처리합니다. 

     

    #`.exec()` vs `.then()`

    Mongoose쿼리는 `.then()`  함수를 지원하므로 "thenable"이라고 할 수 있습니다 .이것은 `.exec()`를 사용하지 않고도 `.then()`을 직접 호출하여 쿼리를 처리할 수 있음을 의미합니다. 그러나 `.then()`함수만으로는 일반적인 프로미스의 모든 기능을 제공받을 수 없습니다. 

     

    예를 들어

    const query = Model.find({ name: 'Neo' });
    
    query.then(function (result) {
      console.log(result);
    });

    위의 코드에서 `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()` 와 같은 비동기 작업에서 내장 프로미스를 사용합니다. 

     

     

     

Designed by Tistory.