Как и все остальные, я провел дни, пытаясь понять это. Я был в этой теме, пробуя каждую комбинацию того, что вы все сказали, и ничего. Я, наконец, пошел в AppData / Local / Microsoft / VisualStudio и удалил все папки там. Затем приступил к отключению всего в моем Антивирусе, и я, наконец, получил базовую установку, чтобы пройти весь путь. Разочарование, но, надеюсь, это поможет кому-то, кто все пробовал.
У вас есть проблема с областью действия.
Это пример для воспроизведения вашей проблемы:
ques
- глобальная переменная, которая обновляется в цикле for, поэтому при асинхронности Код завершается, выполнение будет считывать глобальную переменную с последним значением ques = result[i]
.
'use strict'
const result = ['a', 'b', 'c']
const mcqAll = []
var ques
for (var i = 0; i < result.length; i++) {
ques = result[i]
var sql_test_q_ops = 'SELECT op_text, op_id FROM mc_ops WHERE q_id = ' + result[i].q_id
query(sql_test_q_ops)
.then(() => {
mcqAll.push({ i: ques })
console.log(mcqAll)
})
}
function query() {
return new Promise(resolve => setTimeout(resolve, 100))
}
Но, если вы просто объявите ques
следующим образом:
for (var i = 0; i < result.length; i++) {
const ques = result[i]
const sql_test_q_op...
все будет работать.
Хорошей практикой является использование const
или let
вместо var
, поскольку последний создает опасную глобальную переменную области действия.
Что касается вашего комментария: вывод пустой, потому что этот цикл for является синхронизированным, поэтому вы отвечаете синхронизированным способом на ответ.
Пример того, как управлять этим делом, может быть таким:
'use strict'
const result = ['a', 'b', 'c']
const mcqAll = []
const promiseArray = result.map(ques => {
const sql_test_q_ops = 'SELECT op_text, op_id FROM mc_ops WHERE q_id = ' + ques.q_id
return query(sql_test_q_ops)
.then(() => { mcqAll.push({ i: ques }) })
})
// Wait for all the query to complete before rendering the results
Promise.all(promiseArray)
.then(() => {
console.log({ mcqAll });
res.render('mcqAllPage', { mcqAll })
})
.catch(err => res.send(500)) // this is an example
function query() {
return new Promise(resolve => setTimeout(resolve, 100))
}
Учтите, что существует множество возможностей для реализации этого:
in
вместо запроса для каждого q_id
и управляя результатом с помощью некоторого кода для группировки результатов Идите глубже и выберите тот, который лучше всего соответствует вашим потребностям.
Важно: .catch
всегда цепочка обещаний!