Моя программа реагирует очень странно. Когда я нажимаю кнопку и вызывается selectService(), он обрабатывается правильно, но последние операторы if / else ведут себя странно, так как показывают сообщения как части if, так и части else. Иногда показывает старые сообщения, а затем новые.
var i = 0;
function selectService() {
$("#tblServices tr").filter(':has(:checkbox:checked)').each(function() {
//i = 1; // to check if the looping has been done or not
//alert(i);
var url = '@Url.Action("CreateInvoice")';
var data = {
fk_BookingID: $("#Booking_ID").val(),
fk_ServiceID: $("td:eq(0)", this).text()
}
$.post(url, data, function(response) {
if (response.ReturnStatusJSON === true) {
alert(response.ReturnStatusJSON);
return true;
} else {
swal("Sorry !", response.ReturnMessageJSON, "error");
return false;
}
});
i = 1;
});
if (i === 0) {
swal("Sorry !", "You must select at least one service", "error");
return;
}
if (i > 0) {
var url2 = '@Url.Action("UpdateBookingInvoiceGeneration")';
var data2 = {
Booking_ID: $("#Booking_ID").val()
}
$.post(url2, data2, function(response) {
if (response.ReturnStatusJSON === true) {
swal("Done", response.ReturnMessageJSON, "success");
$('.selectColumn').prop("checked", false);
return;
} else {
swal("Sorry !", response.ReturnMessageJSON, "error");
}
});
}
}
Что происходит? Почему он так себя ведет? Я использую последнюю версию Chrome.
Обновлять:
При отладке я увидел совсем другую проблему. Я выбрал 3 флажка в таблице, по которым каждая петля должен запускаться как минимум 3 раза, но сначала он запускался 2 раза и перешел к если (i> 0), выполнил это полностью и снова перескочил, чтобы выбрать функцию служб, и побежал для третьей проверки, оставшийся.
Это не может быть из одного и того же HTTP-запроса, поэтому я предполагаю, что это либо новый запрос от .each(), либо selectService(), вызываемый дважды. Попробуй добавить логи :) PS. почти уверен, что вы можете делать только if (response.ReturnStatusJSON)
@David даже иногда каждый цикл существует без цикла по нескольким строкам, но иногда он выполняется полностью
@mtefi: пробовал, но та же проблема
@Stacky: Я не уверен, что этот комментарий вообще должен означать. Но в одном я уверен, что вам нужно отладить и уменьшить проблему. Когда происходит что-то конкретное и неожиданное, вы отлаживаете именно это. Определите, что именно происходит в отладчике. В какой конкретной строке кода происходит что-то неожиданное? Какие были входы? Чего вы ожидали? Почему?
если (i> 0) этот блок создает проблему
@Stacky: Хорошо, а в чем "проблема" в этом случае? Что вы ожидаете от if (i > 0) при любом заданном значении i?
@ Дэвид: я увидел очень странную проблему при отладке. Я выбрал 3 флажка в таблицах, на которых каждый цикл должен запускаться по крайней мере 3 раза, но он выполнялся 2 раза и перешел к if (i> 0) выполнил это, а затем снова перешел, чтобы выбрать функцию служб, и побежал для 3-го проверять
Вы знаете, что $.post - это асинхронный метод?
@ Teemu: да, хотя я новичок в этом, но я знаю, как справиться с таким поведением?
@ Дэвид: ты видел мой комментарий?
Похоже, вы ожидаете, что возврат из обработчика первого поста разорвет цикл each. Они этого не делают, цикл выполняется задолго до того, как первый вызов AJAX запустит обработчик done. Это означает, что i никогда не является 0 в состоянии первого if. Это также означает, что второй if всегда проходит (i всегда 1) во время работы if. Затем идет странная часть: что такое response.ReturnStatusJSON и response.ReturnMessageJSON, $.post здесь не jQuery post?
операторы return в обратных вызовах из вашего метода $ .post не делают ничего полезного, если это то, на что вы надеялись (хотя это все еще не совсем понятно). В этом контексте не к чему возвращаться. Они не нарушают ваш цикл и не вызывают возврата вашей внешней функции. Фактически, поскольку вызовы ajax являются асинхронными, ваш цикл и внешняя функция уже будут завершены к моменту выполнения кода, обрабатывающего ответ от вызова ajax.
@Teemu: использовал $ .ajaxSetup ({async: false}); это и сработало
@Stacky async:false устарел в некоторых браузерах, вы увидите предупреждение в консоли, когда будете его использовать, и поэтому можете ожидать, что он может перестать работать в будущем. Из-за однопоточности он полностью блокирует пользовательский интерфейс браузера во время запроса, что, если по какой-то причине оно неожиданно длинное, может заставить пользователя подумать, что весь браузер разбился. Очевидно, по той же причине это замедляет вашу страницу. Это основные причины, по которым он устарел. Это может предоставить вам быстрое исправление, но я настоятельно рекомендую вам в ближайшее время запланировать рефакторинг кода, чтобы он работал без него.



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Думаю, я понимаю, что вы пытаетесь сделать, и использование переменной для проверки выполнения блока внутри .each - плохая практика. То же самое и с синхронными запросами.
Итак, вот предложение, надеюсь, оно поможет
function selectService() {
// First, manage the case where the user didn't select a service
if ($("#tblServices tr").filter(':has(:checkbox:checked)') === null) { // or check array length
swal("Sorry !", "You must select at least one service", "error");
return;
}
// Then, if he has
$("#tblServices tr").filter(':has(:checkbox:checked)').each(function() {
var url = '@Url.Action("CreateInvoice")';
var data = {
fk_BookingID: $("#Booking_ID").val(),
fk_ServiceID: $("td:eq(0)", this).text()
}
// Do your first request
$.post(url, data, function(response) {
if (response.ReturnStatusJSON === true) {
alert(response.ReturnStatusJSON);
var url2 = '@Url.Action("UpdateBookingInvoiceGeneration")';
var data2 = {
Booking_ID: $("#Booking_ID").val()
}
// Still in the callback, do the second one if you want it done AFTER
// getting the result for the first one
$.post(url2, data2, function(response) {
if (response.ReturnStatusJSON === true) {
swal("Done", response.ReturnMessageJSON, "success");
$('.selectColumn').prop("checked", false);
return;
} else {
swal("Sorry !", response.ReturnMessageJSON, "error");
}
});
return true;
} else {
swal("Sorry !", response.ReturnMessageJSON, "error");
return false;
}
});
});
}"То же самое касается использования асинхронных запросов" ... вы имели в виду "То же самое касается использования запросов синхронный"?
Непонятно, что вы описываете. Во-первых, ваш вызов AJAX выполняется в цикле. Так почему же вы не ожидаете, что это будет сделано несколько раз? Что касается if / else, мы можем вам гарантировать только то, что любой данный экземпляр этого кода абсолютно не выполняет оба этих блока. Но поскольку вы выполняете этот код несколько раз с потенциально разными значениями времени выполнения, то, что вы видите, звучит как ожидаемое поведение. Так в чем конкретно проблема?