jQuery: заставить вторую функцию ждать выполнения, пока первая функция не будет завершена

Я пытаюсь использовать when и done, чтобы вторая функция запускалась только после выполнения первой, но она не работает. Вот чего я пытаюсь добиться:

Сначала я использую $("#jobshome").load("jobs/newest-jobs .js-toprow"); для загрузки div с внешней страницы (в том же домене, здесь нет перекрестного домена), затем, после полной загрузки, запускается следующий скрипт, который представляет собой простой текстовый слайдер. Но теперь внешний HTML больше не загружается внутри «#jobshome».

Результат, который я получаю, когда не использую этот подход, заключается в том, что весь внешний div будет загружаться внутри одного слайдера, а это не то, что мне нужно.

Если я использую начальную часть, как эта, она работает, но не так, как ожидалось:

$(function(){$("#jobshome").load("jobs/newest-jobs .js-toprow");});
        $(function(){

    //rotation speed and timer

Мой код выглядит следующим образом:

jQuery(document).ready(function($) {

  $.when(function() {
    $("#jobshome").load("jobs/newest-jobs .js-toprow");
  }).done(function() {

    //rotation speed and timer
    var speed = 3000;
    var run = setInterval(rotate, speed);
    var slides = $('.js-toprow');
    var container = $('#jobshome');
    var elm = container.find(':first-child').prop("tagName");
    var item_height = container.height();
    var previous = 'prevabc'; //id of previous button
    var next = 'nextabc'; //id of next button
    slides.height(item_height); //set the slides to the correct pixel height
    container.parent().height(item_height);
    container.height(slides.length * item_height); //set the slides container to the correct total height
    container.find(elm + ':first').before(container.find(elm + ':last'));
    resetSlides();


    //if user clicked on prev button

    $('#buttonsabc a').click(function(e) {
      //slide the item

      if (container.is(':animated')) {
        return false;
      }
      if (e.target.id == previous) {
        container.stop().animate({
          'top': 0
        }, 1500, function() {
          container.find(elm + ':first').before(container.find(elm + ':last'));
          resetSlides();
        });
      }

      if (e.target.id == next) {
        container.stop().animate({
          'top': item_height * -2
        }, 1500, function() {
          container.find(elm + ':last').after(container.find(elm + ':first'));
          resetSlides();
        });
      }
      //cancel the link behavior            
      return false;

    });

    //if mouse hover, pause the auto rotation, otherwise rotate it    
    container.parent().mouseenter(function() {
      clearInterval(run);
    }).mouseleave(function() {
      run = setInterval(rotate, speed);
    });


    function resetSlides() {
      //and adjust the container so current is in the frame
      container.css({
        'top': -1 * item_height
      });
    }

  });
});
//a simple function to click next link
//a timer will call this function, and the rotation will begin

function rotate() {
  jQuery('#nextabc').click();
}
#carouselabc {
  position: relative;
  width: 60%;
  margin: 0 auto;
}

#slidesabc {
  overflow: hidden;
  position: relative;
  width: 100%;
  height: 250px;
}

#areadoslideabc {
  list-style: none;
  width: 100%;
  height: 250px;
  margin: 0;
  padding: 0;
  position: relative;
}

#slidesabcdef {
  width: 100%;
  height: 250px;
  float: left;
  text-align: center;
  position: relative;
  font-family: lato, sans-serif;
}


/* Styling for prev and next buttons */

.btn-barabc {
  max-width: 346px;
  margin: 0 auto;
  display: block;
  position: relative;
  top: 40px;
  width: 100%;
}

#buttonsabc {
  padding: 0 0 5px 0;
  float: right;
}

#buttonsabc a {
  text-align: center;
  display: block;
  font-size: 50px;
  float: left;
  outline: 0;
  margin: 0 60px;
  color: #b14943;
  text-decoration: none;
  display: block;
  padding: 9px;
  width: 35px;
}

a#prevabc:hover,
a#next:hover {
  color: #FFF;
  text-shadow: .5px 0px #b14943;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="carouselabc">
  <div class="btn-barabc">
    <div id="buttonsabc">
      <a id="prevabc" href="#">Previous</a>
      <a id="nextabc" href="#">Next</a>
    </div>
  </div>
  <div id="slidesabc">
    <div id="jobshome"></div>
  </div>
</div>

Источник скрипта: https://codepen.io/TyStelmach/pen/yygvNK


person Matt    schedule 11.09.2018    source источник
comment
Вы думали об использовании глобального флага. Вы можете использовать оператор if, чтобы увидеть, существует ли состояние как истинное или ложное. Я использую его все время, и это работает для меня.   -  person Cam    schedule 12.09.2018
comment
Я использовал console.log("text"); внутри каждой функции, чтобы проверить, все ли работает. Только вторая функция есть.   -  person Matt    schedule 12.09.2018
comment
Вы пытались использовать .then вместо .done. makandracards.com/makandra/   -  person Cam    schedule 12.09.2018
comment
Да. Это все еще не работает.   -  person Matt    schedule 12.09.2018


Ответы (1)


Почему вы не используете обратный вызов функции load()?

$("#jobshome").load("jobs/newest-jobs .js-toprow", () => {
   //do stuff after loading the html
}); 

when не работает, потому что он ожидает объект Promise или Deferred, и если это не так, он обрабатывает переданное значение как разрешенное Deferred (что в основном означает, что он не ждет, а сразу выполняет then/done).

person vicbyte    schedule 11.09.2018
comment
Что означает =>? - person Matt; 12.09.2018
comment
Функция стрелки, вы также можете заменить () => на function(), подробнее об этом: stackoverflow.com/questions/24900875/ - person vicbyte; 12.09.2018
comment
Я использовал ваше решение, и оно сработало. Но тогда я больше не получаю цикл слайд-шоу. - person Matt; 12.09.2018
comment
Не уверен, что вы подразумеваете под циклом слайд-шоу, но поместили ли вы весь код, который должен запускаться после загрузки контента, в функцию обратного вызова? - person vicbyte; 12.09.2018
comment
Слайд-шоу взято отсюда. Он выполняет цикл, но после того, как я попробовал ваше решение, похоже, что оно все еще работает вечно, но есть проблема с вложенностью элементов. - person Matt; 12.09.2018
comment
Поместил все внутри обратного вызова сейчас. Такой же. - person Matt; 12.09.2018
comment
Не могли бы вы закомментировать все строки, содержащие это: container.find(elm + ':last').after(container.find(elm + ':first')); И проверить, появляется ли слайд-шоу? - person vicbyte; 12.09.2018
comment
Сделал это. Теперь он не скользит к следующему элементу. Проблема, с которой я сталкиваюсь, заключается в том, что он хорошо скользит до определенного элемента, затем макет ломается, как будто есть плавающее право (CSS), а затем он исчезает. Можете ли вы протестировать код локально? - person Matt; 12.09.2018
comment
Хорошо, большое спасибо, сэр, я обязательно последую совету. - person Matt; 12.09.2018