Почему код не работает, если у меня нет асинхронности в предварительном промежуточном программном обеспечении?

    curUser.password = newPassword;
  curUser.passwordConfirm = passwordConfirm;
  await curUser.save();

У меня есть этот код для выполнения в этой функции:

    exports.updatePassword = catchAsync(async (req, res, next) => {
  // 1-) Get user from the collection
  const { currentPassword, newPassword, passwordConfirm } = req.body;

  const curUser = await User.findById(req.user.id).select('+password');

  if (!curUser) {
    return next(new AppError('Token is invalid !', 404));
  }

  // 2-) Check if posted current password is correct
  if (!(await curUser.correctPassword(curUser.password, currentPassword))) {
    return next(new AppError('Password is incorrect !', 401));
  }

  curUser.password = newPassword;
  curUser.passwordConfirm = passwordConfirm;
  await curUser.save();
  //findByIdAndUpdate yerine save ederek kullanmamızın sebebi oluşturmuş olduğumuz pre middlewareleri ile validatorların update işleminde
  //çalışmayacak olması

  //3-) Log user in, send JWT
  createTokenAndSend(200, res, curUser._id);
});

И, кроме того, у меня есть одно промежуточное ПО в userModel для создания passwordChangedAt в базе данных, когда пользователь обновляет свой пароль:

userSchema.pre('save', async function(next) {
  if (!this.isModified('password') || this.isNew) return next();
  //Eğer yeniyse bu fonksiyonu çalıştırmamasını ve direk diğer middleware'e geçmesini belirttik

  this.passwordChangedAt = Date.now - 1000;
});

Итак, проблема в том, почему этот промежуточный метод должен быть асинхронным. Когда я удаляю «asycn» до того, как эта предварительная функция промежуточного программного обеспечения получила ошибку в почтальоне. На самом деле это не ошибка, просто posmtan не может получить такой ответ: Это изображение этого

Итак, почему у меня возникает эта проблема, когда я удаляю асинхронность из этого предварительного промежуточного программного обеспечения?


person Lepuz    schedule 07.05.2020    source источник


Ответы (1)


Ваше промежуточное программное обеспечение должно либо вызывать функцию next, либо возвращать обещание (которое в конечном итоге разрешается), иначе оно никогда не будет считаться «выполненным», что приведет к вашему бесконечному запросу. (https://mongoosejs.com/docs/middleware.html)

Если вы посмотрите на свое промежуточное ПО, оно покажет, что вы не вызываете next, если !this.isModified('password') || this.isNew оценивается как false. Следовательно, если промежуточное ПО не возвращает обещание, оно никогда не будет считаться выполненным.

Использование async преобразует вашу функцию для возврата обещания, тем самым подчиняясь контракту промежуточного программного обеспечения.

В качестве альтернативы попробуйте удалить async и добавить next(); в конец функции после обновления passwordChangedAt.

person abondoa    schedule 07.05.2020
comment
Спасибо за ответ, теперь я понимаю, почему почтальон попадает в бесконечный цикл - person Lepuz; 08.05.2020