Проблема с подсчетом очков викторины NodeJS

Поэтому я сделал веб-сайт с викториной, используя «стек MEN» (без React), если его можно так назвать. Ссылка на репо здесь.

При локальном тестировании приложения викторина работает должным образом. Без вопросов. Оценка производится после того, как пользователь отправляет форму. У меня есть несколько ключевых слов для каждого вопроса, и при отправке я проверяю, ввел ли пользователь какие-либо ключевые слова, которые я установил. Код для этого можно увидеть ниже.

router.post("/submit", (req, res) => {
  let sub = Object.values(req.body);
  let ans = [];
  sub.forEach((opt, idx) => {
    opt = opt.toLowerCase();
    ans[idx] = opt.split(" ");
  });
  let score = 0;
  ans.forEach(async (opt, idx) => {
    const corr = await Question.findOne({
      index: idx,
    });
    corr.answer = corr.answer.toLowerCase();
    let correct = corr.answer.split(" ");
    let res = correct.some((val) => {
      return opt.indexOf(val) >= 0;
    });
    if (res) {
      score += 10;
    }
  });
  setTimeout(async () => {
    const user = await User.findByIdAndUpdate(req.user.id, {
      score,
      completed: true,
      submittedAt: Date.now(),
      answers: sub,
    });
  }, 1000);

  // console.info(req.user.id);
  res.render("finished");
});

Как видите, мне пришлось использовать setTimeout для подсчета очков, так как без него это не работало. Я предположил, что это вызвано асинхронным характером вычислительной функции. Если вы можете предложить лучшую альтернативу, это будет здорово. Ниже приведен пример одного вопроса и его ключевых слов:

{
    description: "A company was started by the Maharaja of Mysore, Nalvadi Krishnaraja W..."
    answer: "vote voting voter voters indelible ink"
    index: 3
    __v: 0
}

После запуска викторины у нас было около 150 участников. При подаче возникла одна проблема; не все оценки пользователей рассчитывались правильно. Некоторые из них были связаны с разными ответами на ключевые слова, но я не смог найти причину для других.

Один из таких необъяснимых случаев был следующим. На первом изображении представлена ​​работа в самом викторине, на втором — тест, который я сделал только что, используя те же ответы, что и у этого участника:

Фактическая подача:

{
    score: 0
    completed: true
    answers: [
      "Trump Towers", "Shakuntala Devi", "Sir", "Voter ink", "",
      "Indian Constitution", "Saera jahe se accha", "Sunfeast open",
      "Dunlop", "Robert Clive", "APJ Abdul Kalam", 
      "Signing the ordinance in Indian emergency",
      "Indian nuclear operation in pokhran", "Mohammad Salim",
      "Swami Vivekananda", "Bubble wrap", "", "Inquilab",
      "Chintaman ganesh temple", "Jamtara"
    ]
}

Мой тест:

{
    score: 140
    completed: true
    answers: [
      "Trump Towers", "Shakuntala Devi", "Sir", "Voter ink", "",
      "Indian Constitution", "Saera jahe se accha", "Sunfeast open",
      "Dunlop", "Robert Clive", "APJ Abdul Kalam", 
      "Signing the ordinance in Indian emergency",
      "Indian nuclear operation in pokhran", "Mohammad Salim",
      "Swami Vivekananda", "Bubble wrap", "", "Inquilab",
      "Chintaman ganesh temple", "Jamtara"
    ]
}

Как видите, ответы абсолютно одинаковы. Даже случаи одинаковые. Правильная оценка для вышеуказанных представлений составляет 140, как я получил выше.

Я предполагаю (дикое предположение), что проблема может быть из-за setTimeout. Любая альтернатива этому методу подсчета очков будет полезна.

Буду благодарен за любую помощь по этому поводу. Заранее спасибо.

Добро пожаловать в Stack Overflow! Пожалуйста, посетите тур , посетите справочный центр и прочитайте , задавая хорошие вопросы. Пожалуйста, включите в вопрос фактический код, а не его изображения.

Scott Sauyet 14.12.2020 16:22

Привет, @ScottSauyet. Я добавил фактический фрагмент кода в вопрос. Сейчас все в порядке?

Arka Seth 14.12.2020 20:31

Да, это помогает, но было бы полезно сделать то же самое для example question, actual submission и my test.

Scott Sauyet 14.12.2020 20:37

Я предлагал вам преобразовать их в текст. Что-то вроде {_id: ObjectId("5f3231922..."), description: "A company was started by...", answer: "vote voting ...", index: 3, __v: 0}

Scott Sauyet 14.12.2020 20:42

@ScottSauyet да ... Извините за это. Я это понял и сразу удалил свой комментарий. Я внес необходимые изменения. Я просто опустил ObjectId, так как в данном случае он не имеет значения. Надеюсь, это нормально? Спасибо, что терпели меня.

Arka Seth 14.12.2020 20:49

Без проблем. Новичкам в сообществе всегда требуется некоторое время, чтобы привыкнуть к его нормам. Спасибо за изменения.

Scott Sauyet 14.12.2020 20:50
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
6
152
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Не реконструируя слишком много вашего кода, я не могу быть уверен, но подозреваю, что вы правы в отношении проблемы асинхронности.

Есть и другие способы решить эту проблему (на ум приходит Promise.all), одна из возможностей — использовать асинхронную версию forEach, а затем дождаться результата перед вызовом User.findByIdAndUpdate (теперь без тайм-аута). Я не использовал его, но быстрый поиск async forEach выдал статью, которая выглядит многообещающе.

Это, вероятно, потребует, чтобы обратный вызов также передавался в router.post асинхронно.

Если этого не произойдет, я бы рассмотрел методы создания минимального воспроизводимого примера. Этот процесс часто помогает вам найти ответ самостоятельно. А когда это не так, это дает потенциальным помощникам что-то маленькое, чтобы пожевать.

Хорошо... Тогда я посмотрю на это. Я также не знал, что существует асинхронная версия forEach.

Arka Seth 15.12.2020 14:31

Другие вопросы по теме