функция jquery AJAX .done() выполняется, но работает не так, как ожидалось

#javascript #php #jquery #ajax #phpmailer

Вопрос:

У меня есть следующие две функции jquery.

 // GET CHAT MESSAGES
let takeDown = true;
setInterval(function(){
  $.ajax({
    type: 'POST',
    url: 'processes/get-chat.php',
    data: 'incoming_id=' incoming_id,
    dataType: 'json',
    success: function(json){
      chatBox.html(json.html);
      $("#theStatus").html(json.status);
      $("#typing").html(json.typing);

      if(!chatBox.hasClass("active") amp;amp; takeDown === true) {
        takeDown = false;
        $('html,body').animate({scrollTop: document.body.scrollHeight}, "fast");
      }
    }
  });
}, 500);

// INSERT CHAT MESSAGE
sendBtn.on('click', function(e){
  e.preventDefault();
  var form = $(this).closest("form");
  var dataString = form.serialize();
  inputField.focus();
  $.ajax({
    type: 'POST',
    url: 'processes/chat.php',
    data: dataString,
    dataType: 'json',
    success: function(json){
      inputField.val('');
      $('html,body').animate({scrollTop: document.body.scrollHeight}, "fast");
    }
  }).done(function(data){
    if(data.status == 'send'){
      $.ajax({
        type: 'POST',
        url: 'processes/chat-mail.php',
        data: 'name=' data.name 'amp;email=' data.email 'amp;msg=' data.message,
        success: function(data){
          console.log(data);
        }
      });
    }
  });
});
 

Теперь здесь функция insert chat вставляет сообщение в базу данных, а функция get chat извлекает сообщения из базы данных и отображает их обратно пользователю. Кроме того, сообщение, отправленное прямо сейчас, мгновенно извлекается с помощью первой функции выше.

Как вы можете видеть, вторая функция использует .done() метод. Это используется для отправки электронного письма другому пользователю, если он/она находится в автономном режиме. Это работает нормально. Однако это замедляет работу функции get chat. Функция get chat, описанная выше, выполняется только после .done() того, как метод в функции insert chat завершил выполнение, и .done() завершает его выполнение, когда почта успешно отправлена со стороны сервера. Теперь отправка электронной почты занимает некоторое время. Это замедляет поиск в чате на 5-10 секунд. Я ожидал .done() , что буду работать в фоновом режиме, не нарушая другие функции на странице. Однако это работает не так, как ожидалось.

На стороне сервера (chat-mail.php)

 $name  = (!empty($_POST['name']))?$_POST['name']:null;
$email = (!empty($_POST['email']))?$_POST['email']:null;
$msg   = (!empty($_POST['msg']))?$_POST['msg']:null;

if($_POST){
  $sub = $settings['site_name'].' - '.$user['name'][0].' sent you a new message';
  $message = mailHead();
  $message .= '<div class="mail-body">
                <p>Hi '.$name.'</p>
                <p><b>'.$user['name'][0].'</b> sent you a new message.</p>
                <p class="chatMessage">'.$msg.'</p>
                <p>Please open '.$settings['site_name'].' app on your phone to respond now. It's joyful to see that you are enjoying your stay at <b>'.$settings['site_name'].'</b>.</p>
                <p>
                  Best Wishes<br>
                  '.$settings['site_name'].' Team
                </p>
              </div>';
  $message .= mailFoot();
  // echo mailSender($sub, $message, $f['email']);
  echo mailSender($sub, $message, 'jhajinamaste@gmail.com');
}
 

chat.php

 $stmt = $pdo->prepare("INSERT INTO messages(incoming_msg_id, outgoing_msg_id, msg)VALUES(:imsg, :omsg, :msg)");
$stmt-> bindValue(':imsg', $imsg);
$stmt-> bindValue(':omsg', sessionUser());
$stmt-> bindValue(':msg', encrypt($chatMsg, ENCRYPTION_KEY));
$stmt-> execute();

if($stmt){
  $stmt = $pdo->prepare("SELECT name, email, last_activity, notify_email_messages FROM users WHERE id = :imsg");
  $stmt-> bindValue(':imsg', $imsg);
  $stmt-> execute();
  $f = $stmt->fetch();

  if($f['notify_email_messages'] == 'yes' amp;amp; minsDiff($f['last_activity']) >= 5){
    $status = ($f['notify_email_messages'] == 'yes' amp;amp; minsDiff($f['last_activity']) >= 5)?'send':'ok';
    echo json_encode(array('name' => $f['name'], 'email' => $f['email'], 'status' => $status, 'message' => $chatMsg));
  }
}
 

Комментарии:

1. Почему бы просто не отправить электронное письмо напрямую, chat.php вместо того, чтобы вызывать еще один обратный переход на сервер (отправляя обратно данные, которые просто сообщают клиенту сделать еще один запрос на сервер, содержащий информацию, о которой сервер уже знал несколькими мгновениями ранее). Это должно сэкономить некоторую пропускную способность. Я бы предположил, что, возможно, у вас возникли проблемы, если на вашем PHP-сервере есть только один поток, который он может посвятить вашей сессии. Сетевой инструмент вашего браузера должен сообщить вам, находятся ли запросы в очереди, если вы посмотрите на график с течением времени

2. P. s. в целом, веб-сайты-это гораздо лучшая технология для доставки приложения для чата, чем AJAX

3. @ADyson означает ли это, что AJAX «плох» или технология «не стоит того», чтобы использовать ее для приложений чата php mysql?

4. Ну, это плохо в том смысле, что это не в реальном времени, поэтому всегда будет несколько секунд, прежде чем вы получите сообщение из-за тайм-аута. И если вы попытаетесь сделать это в режиме реального времени, сократив время ожидания, вы перегрузите свой сервер (и, возможно, также клиент) огромным количеством запросов. Кроме того, AJAX каждый раз генерирует новый HTTP-запрос, который имеет накладные расходы (рукопожатие, отправка заголовков и т.д.), Что еще больше увеличивает использование пропускной способности. AJAX отлично подходит для запросов по требованию или нечастых асинхронных запросов к серверу, но не подходит для использования в реальном времени.

5. Напротив, подключение к websocket нужно открыть только один раз, и вы получите мгновенную, недорогую двустороннюю связь в режиме реального времени между клиентом и сервером-вам не нужно полагаться на тайм-ауты и опросы клиента, потому что сервер может напрямую отправлять сообщения клиенту через сокет, когда захочет.