await
와 Promise
를 함께 사용하는 것은 비동기 작업을 처리하기 위한 패턴 중 하나이다. await
키워드를 사용하여 Promise
의 해결 결과를 기다릴 수 있습니다.
bcrypt.hash
함수는 콜백 기반의 비동기 함수이기 때문에 await
를 직접 사용할 수 없다. 따라서 new Promise
를 사용하여 비동기 작업을 Promise
객체로 감싸고, 해당 Promise
객체의 해결 결과를 await
를 통해 기다리는 구조로 짤 수 있다.
즉, await new Promise
를 사용함으로써 비동기 작업을 동기적인 코드로 표현하고, 해당 작업의 성공 여부를 resolve
와 reject
를 통해 처리할 수 있다. 비동기 작업이 성공적으로 완료되면 resolve
함수를 호출하여 해시화된 비밀번호를 반환하고, 오류가 발생하면 reject
함수를 호출하여 예외를 처리할 수 있다.
Promise
는 비동기 작업의 결과를 나타내는 객체. Promise
는 보통 비동기 작업을 수행하는 함수 내부에서 생성되고, 작업이 완료되면 resolve
나 reject
함수를 호출하여 작업의 성공 또는 실패를 알린다.resolve
함수는 Promise
를 성공 상태로 만들며, 그 결과로 비동기 작업의 성공적인 완료를 나타냅니다. 위의 코드에서 bcrypt.hash
함수의 결과를 resolve
함수로 전달하여 비밀번호를 해시화한 결과를 반환합니다.reject
함수는 Promise
를 실패 상태로 만들며, 그 결과로 비동기 작업의 실패를 나타냅니다. 위의 코드에서 bcrypt.hash
함수에서 오류가 발생한 경우 reject
함수로 해당 오류를 전달하여 예외 처리를 할 수 있습니다.const foundUser = await User.findOne({ userId: user.userId })
if (!foundUser) {
return res.status(409).json({
status: 409,
message: ‘아이디를 확인해주세요.’,
})
}
const isPasswordCorrect = await bcrypt.compare(user.password, foundUser.hashedPassword)
위와 같이 DB에서 찾은 사용자 정보를 활용해서 비밀번호가 일치하는지 확인하는 코드를 작성하였는데, 어떤 방법을 사용해봐도 foundUser.hashedPassword
부분과 관련해서 다음과 같은 오류를 벗어날 수가 없었다.
Argument of type 'string | undefined' is not assignable to parameter of type 'string'. Type 'undefined' is not assignable to type 'string'.
그러다가 혹시 몰라서 collection을 추가해 보았는데.. 해결이 되었다...! 왜....?
const foundUser = await User.collection.findOne({ userId: user.userId })
두 메서드의 가장 큰 차이점은 User.collection.findOne()
은 MongoDB의 Collection에서 제공하는 메서드이고, User.findOne()
은 Mongoose 모델에서 제공하는 메서드라는 것이다.
따라서, User.collection.findOne()
은 MongoDB에서 직접 조회된 Document
객체를 return 하고 User.findOne()
은 Mongoose에서 조회된 Document
객체를 return 한다.
그러니까.. mongoose를 사용하면서 미묘한 차이 때문에 문제가 발생했 던 것이다.
추후에 ORM(Object-Relational Mapping)에 따른 메서드와 return 값에 대한 차이를더 공부해보는게 좋을 것 같다.