Поэтому я сделал веб-сайт с викториной, используя «стек 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
. Любая альтернатива этому методу подсчета очков будет полезна.
Буду благодарен за любую помощь по этому поводу. Заранее спасибо.
Привет, @ScottSauyet. Я добавил фактический фрагмент кода в вопрос. Сейчас все в порядке?
Да, это помогает, но было бы полезно сделать то же самое для example question
, actual submission
и my test
.
Я предлагал вам преобразовать их в текст. Что-то вроде {_id: ObjectId("5f3231922..."), description: "A company was started by...", answer: "vote voting ...", index: 3, __v: 0}
@ScottSauyet да ... Извините за это. Я это понял и сразу удалил свой комментарий. Я внес необходимые изменения. Я просто опустил ObjectId, так как в данном случае он не имеет значения. Надеюсь, это нормально? Спасибо, что терпели меня.
Без проблем. Новичкам в сообществе всегда требуется некоторое время, чтобы привыкнуть к его нормам. Спасибо за изменения.
Не реконструируя слишком много вашего кода, я не могу быть уверен, но подозреваю, что вы правы в отношении проблемы асинхронности.
Есть и другие способы решить эту проблему (на ум приходит Promise.all
), одна из возможностей — использовать асинхронную версию forEach
, а затем дождаться результата перед вызовом User.findByIdAndUpdate
(теперь без тайм-аута). Я не использовал его, но быстрый поиск async forEach
выдал статью, которая выглядит многообещающе.
Это, вероятно, потребует, чтобы обратный вызов также передавался в router.post
асинхронно.
Если этого не произойдет, я бы рассмотрел методы создания минимального воспроизводимого примера. Этот процесс часто помогает вам найти ответ самостоятельно. А когда это не так, это дает потенциальным помощникам что-то маленькое, чтобы пожевать.
Хорошо... Тогда я посмотрю на это. Я также не знал, что существует асинхронная версия forEach
.
Добро пожаловать в Stack Overflow! Пожалуйста, посетите тур , посетите справочный центр и прочитайте , задавая хорошие вопросы. Пожалуйста, включите в вопрос фактический код, а не его изображения.