#javascript #jquery
#javascript #jquery
Вопрос:
Я запускаю цикл, и внутри цикла я вызываю функцию. Функция выполняет вызов ajax и возвращает ответ, но проблема в том, что цикл не ожидает ответа, поэтому функция возвращает undefined.
function checkBidStatus(index) {
$.ajax({
type:'get',
url:'/orderbook/checkorderdetails',
success: function(data){
$parsedData = JSON.parse(data);
if($parsedData[index]) {
return "Hello";
} else {
return "Bye";
}
//$("#bid-details .modal-dialog").html(data);
},
error: function (response) {
console.log(response);
}
});
}
let content = '';
for(let i = 1; i <= 10; i ) {
content = '<div>'
(checkBidStatus(i))
'</div>';
}
Комментарии:
1. Проблема в том, что цикл for является синхронным, но вызов ajax является асинхронным. Т. Е. эта функция должна ждать ответа сервера. Поэтому вызывающий объект должен использовать обратные вызовы или обещания, прежде чем перейти к следующему запросу.
2. пожалуйста, уточните с помощью кода
3. Ок … выполняется. Скоро появится код.
4. Вы можете сделать вызов ajax синхронным, определив
async:false
в теле ajax. это простое решение, но оно также блокирует ваш поток пользовательского интерфейса, что означает, что ваш пользовательский интерфейс не будет отвечать во время цикла.5. @ayan_84 синхронный Ajax устарел из-за плохого пользовательского интерфейса, который он предоставляет. Это блокирует браузер во время использования, и длительный запрос (или серия запросов) может создать у пользователя впечатление, что страница разбилась. Кроме того, поскольку она устарела, вы можете ожидать, что браузеры перестанут поддерживать ее в обозримом будущем. Это не очень хороший способ решить проблему. Связывание обещаний было бы более подходящим решением
Ответ №1:
Проблема в том, что цикл for является синхронным, но вызов ajax является асинхронным. Т. Е. эта функция должна ждать ответа сервера. Поэтому вызывающий объект должен использовать обратные вызовы или обещания, прежде чем перейти к следующему запросу.
Существуют элегантные способы выполнения этой задачи с использованием определенных библиотек, таких как async, но «быстрый VanillaJS» способ решения этой задачи с использованием promises был бы примерно таким:
const contentTemplate = '<div>[BID_RESULT]</div>';
const nRequests = 10;
var requestCnt = 0;
var content = '';
function checkBidStatus(index) {
return new Promise((resolve, reject) => {
$.ajax({
type:'get',
url:'/orderbook/checkorderdetails',
success: function(data){
$parsedData = JSON.parse(data);
resolve({ index: index 1, msg: $parsedData ? "Hello" : "Bye" });
},
error: reject
});
// <-- NOTE: there is no return statement at this line. Hence if
// you were to call this function from your for loop, you'd see
// undefined
}
}
Затем вы можете продолжать вызывать эту функцию рекурсивно:
function multipleRequests(){
checkBidStatus(requestCnt)
.then((resp) => { // This runs if the promise RESOLVES (i.e., success)
content = contentTemplate.replace('[BID_RESULT]', resp.msg);
// --- [then do what you want with content] --- //
// Request again
requestCnt ;
if( requestCnt < nRequests ){
multipleRequests();
}
})
.catch(console.error) // This runs if promise rejects (i.e., has an error)
}
// Run:
multipleRequests();
Ответ №2:
Почему бы не использовать обещание внутри и не дождаться этого обещания, чтобы получить требуемый результат, после чего обновить DOM? В вашем методе checkBidStatus вы можете создать обещание и вернуть его. Когда результат ajax будет доступен, разрешите обещание с помощью результата ajax.
Вызывающий метод должен будет дождаться разрешения promise, а затем обновить DOM.
let content = '';
for(let i = 1; i <= 10; i ) {
checkBidStatus(i).then(result => {
content = '<div>' result '</div>';
})
}
Примечание: Я не тестировал код, но что-то подобное должно работать. Также порядок divs, созданных на основе индекса, не гарантируется, поэтому вам может потребоваться позаботиться об этом, если порядок важен.
Комментарии:
1. Я думаю, что это довольно приятно. Я думаю, что комбинация наших ответов должна заставить его работать 🙂
Ответ №3:
Вы должны ждать ответа от сервера для каждой итерации в цикле.
function checkBidStatus(index) {
$.ajax({
type: 'get',
url: '/orderbook/checkorderdetails',
success: function(data) {
$parsedData = JSON.parse(data);
if ($parsedData[index]) {
return {
msg: 'Hello',
index: index 1,
};
} else {
return {
msg: 'Bye',
index: index 1,
};
}
//$("#bid-details .modal-dialog").html(data);
},
error: function(response) {
console.log(response);
},
});
}
let content = '';
let i = 1;
while (i <= 10) {
let { msg, index } = checkBidStatus(i);
content = '<div>' msg '</div>';
i = index;
}