Почему моя программа выполняется как if, так и else?

Моя программа реагирует очень странно. Когда я нажимаю кнопку и вызывается 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), выполнил это полностью и снова перескочил, чтобы выбрать функцию служб, и побежал для третьей проверки, оставшийся.

Непонятно, что вы описываете. Во-первых, ваш вызов AJAX выполняется в цикле. Так почему же вы не ожидаете, что это будет сделано несколько раз? Что касается if / else, мы можем вам гарантировать только то, что любой данный экземпляр этого кода абсолютно не выполняет оба этих блока. Но поскольку вы выполняете этот код несколько раз с потенциально разными значениями времени выполнения, то, что вы видите, звучит как ожидаемое поведение. Так в чем конкретно проблема?

David 14.06.2018 14:24

Это не может быть из одного и того же HTTP-запроса, поэтому я предполагаю, что это либо новый запрос от .each(), либо selectService(), вызываемый дважды. Попробуй добавить логи :) PS. почти уверен, что вы можете делать только if (response.ReturnStatusJSON)

mtefi 14.06.2018 14:25

@David даже иногда каждый цикл существует без цикла по нескольким строкам, но иногда он выполняется полностью

user9677867 14.06.2018 14:26

@mtefi: пробовал, но та же проблема

user9677867 14.06.2018 14:26

@Stacky: Я не уверен, что этот комментарий вообще должен означать. Но в одном я уверен, что вам нужно отладить и уменьшить проблему. Когда происходит что-то конкретное и неожиданное, вы отлаживаете именно это. Определите, что именно происходит в отладчике. В какой конкретной строке кода происходит что-то неожиданное? Какие были входы? Чего вы ожидали? Почему?

David 14.06.2018 14:27

если (i> 0) этот блок создает проблему

user9677867 14.06.2018 14:32

@Stacky: Хорошо, а в чем "проблема" в этом случае? Что вы ожидаете от if (i > 0) при любом заданном значении i?

David 14.06.2018 14:34

@ Дэвид: я увидел очень странную проблему при отладке. Я выбрал 3 флажка в таблицах, на которых каждый цикл должен запускаться по крайней мере 3 раза, но он выполнялся 2 раза и перешел к if (i> 0) выполнил это, а затем снова перешел, чтобы выбрать функцию служб, и побежал для 3-го проверять

user9677867 14.06.2018 14:38

Вы знаете, что $.post - это асинхронный метод?

Teemu 14.06.2018 14:40

@ Teemu: да, хотя я новичок в этом, но я знаю, как справиться с таким поведением?

user9677867 14.06.2018 14:41

@ Дэвид: ты видел мой комментарий?

user9677867 14.06.2018 15:46

Похоже, вы ожидаете, что возврат из обработчика первого поста разорвет цикл each. Они этого не делают, цикл выполняется задолго до того, как первый вызов AJAX запустит обработчик done. Это означает, что i никогда не является 0 в состоянии первого if. Это также означает, что второй if всегда проходит (i всегда 1) во время работы if. Затем идет странная часть: что такое response.ReturnStatusJSON и response.ReturnMessageJSON, $.post здесь не jQuery post?

Teemu 14.06.2018 16:30

операторы return в обратных вызовах из вашего метода $ .post не делают ничего полезного, если это то, на что вы надеялись (хотя это все еще не совсем понятно). В этом контексте не к чему возвращаться. Они не нарушают ваш цикл и не вызывают возврата вашей внешней функции. Фактически, поскольку вызовы ajax являются асинхронными, ваш цикл и внешняя функция уже будут завершены к моменту выполнения кода, обрабатывающего ответ от вызова ajax.

ADyson 14.06.2018 17:11

@Teemu: использовал $ .ajaxSetup ({async: false}); это и сработало

user9677867 14.06.2018 17:41

@Stacky async:false устарел в некоторых браузерах, вы увидите предупреждение в консоли, когда будете его использовать, и поэтому можете ожидать, что он может перестать работать в будущем. Из-за однопоточности он полностью блокирует пользовательский интерфейс браузера во время запроса, что, если по какой-то причине оно неожиданно длинное, может заставить пользователя подумать, что весь браузер разбился. Очевидно, по той же причине это замедляет вашу страницу. Это основные причины, по которым он устарел. Это может предоставить вам быстрое исправление, но я настоятельно рекомендую вам в ближайшее время запланировать рефакторинг кода, чтобы он работал без него.

ADyson 15.06.2018 10:58
Поведение ключевого слова "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) для оценки ваших знаний,...
4
15
104
1

Ответы 1

Думаю, я понимаю, что вы пытаетесь сделать, и использование переменной для проверки выполнения блока внутри .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;
      }
    });

  });

}

"То же самое касается использования асинхронных запросов" ... вы имели в виду "То же самое касается использования запросов синхронный"?

ADyson 15.06.2018 10:58

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