Как дождаться завершения переключения jQuery, прежде чем запускать другую функцию? - PullRequest
0 голосов
/ 20 мая 2018

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

У меня есть три следующих метода:

const toggleContainer = function() {
  addAnswerContainer.toggle("slow");
};

const toggleButtons = function() {
  submitAnswerBtn.toggle("slow");
  cancelAnswerBtn.toggle("slow");
};

const changeText = function() {
  if( addAnswerContainer.is(":hidden") ) {
    addOwnAnswerBtn.text("Add your own answer" );
  }
  else {
    addOwnAnswerBtn.text("Hide adding answer");
  }
};

Все, что я хочу сделать, - это заставить что-то подобное работать:

const toggleUI = function() {
  toggleContainer();
  toggleButtons();
  changeText(); // executes too fast
};

Проблема в том, что changeText() выполняется слишком быстро, и каждый раз, когда он проверяет, addAnswerContainer.is(":hidden") возвращает false, если я не setTimeout это в течение нескольких секунд, а это не то, что я хочу.Я пробовал с обратными вызовами, также с Обещаниями, но я просто не могу заставить это работать.Как я могу заставить changeText() ждать, пока addAnswerContainer.toggle() не выполнит свою работу?

Ответы [ 3 ]

0 голосов
/ 20 мая 2018

Я могу предложить простой, но умный подход, следуя вашим операторам if-else, например так:

const toggleContainer = function() {
  addAnswerContainer.toggle("slow");
  return true;
};

const toggleButtons = function() {
  submitAnswerBtn.toggle("slow");
  cancelAnswerBtn.toggle("slow");
};

const ToggleIfTrue = () => {
  if(addAnswerContainer.is(":hidden") && toggleContainer) { 
    addOwnAnswerBtn.text("Add your own answer" );
  }
  else if (addAnswerContainer.is(!":hidden") && toggleContainer) {
    addOwnAnswerBtn.text("Hide adding answer");
  }
};

Таким образом, внутренний оператор if-else выполняется, только если addAnswerContainer установлен как hidden и наоборот с последним оператором if if

0 голосов
/ 20 мая 2018

Может вернуть $.when обещание из функции переключения и использовать promise() объектов-элементов, которые должны быть разрешены в $.when.

, вызвать следующий шаг в следующем then() цепочке обещаний

Упрощенная демка

const toggleComplete = function(){
   console.log('finished animation id #', this.id)
}

const toggleButtons = function (){
  // toggleComplete only needed for this demo
  let p1=$('#1').toggle('slow',toggleComplete).promise()
  let p2=$('#2').toggle('slow',toggleComplete).promise()
 
  return $.when(p1,p2)
}

toggleButtons().then(_=>console.log('all animations done')/* change text here*/)
div{display:none}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="1">
One
</div>

<div id="2">
Two
</div>
0 голосов
/ 20 мая 2018

.toggle ([длительность] [, завершено])

Необязательный второй аргумент - это функция для вызова после завершения анимации, поэтому просто вызовите toggle с нужнымПерезвоните.Обещания - лучший способ сделать что-то вроде этого:

const toggleContainer = () => new Promise(resolve =>
  addAnswerContainer.toggle("slow", resolve)
);

const toggleButtons = () => new Promise(resolve => {
    submitAnswerBtn.toggle("slow");
    cancelAnswerBtn.toggle("slow", resolve);
});

const changeText = function() {
  if( addAnswerContainer.is(":hidden") ) {
    addOwnAnswerBtn.text("Add your own answer" );
  }
  else {
    addOwnAnswerBtn.text("Hide adding answer");
  }
};

Затем вызовите .then для обещаний связать асинхронные функции:

const toggleUI = function() {
  toggleContainer()
    .then(toggleButtons)
    .then(changeText);
};

Или, если вы хотите toggleContainer иtoggleButtons запустить сразу и ждать только до changeText:

const toggleUI = function() {
  toggleContainer()
  toggleButtons()
    .then(changeText);
};
...