Выполните асинхронную функцию дважды после завершения предыдущей - PullRequest
0 голосов
/ 07 октября 2018

Я пытаюсь выполнить функцию async дважды один за другим.Но проблема в том, что они исполняются вместе.Но я хочу, чтобы 2-е выполнение было запущено после завершения первого.

PS, есть много вопросов по SO, с таким же названием, как этот JavaScript: выполнить асинхронную функцию одну за другой .Но ни один из них не решает мою проблему.

Пожалуйста, отметьте Fiddle

$(document).ready(function() {
  function typeWriter(element, msg, speed, index = 0) {
    if (index < msg.length) {
      $(element).html($(element).html() + msg.charAt(index++));
      setTimeout(function() {
        typeWriter(element, msg, speed, index);
      }, speed);
    }
  }

  $('.intro').fadeIn(function() {
    const greet = new Promise(function(resolve, reject) {
      typeWriter('#sayHello', "Hello !!", 200);
      resolve();
    });
    greet.then(function() {
      typeWriter('#myName', "I'm learning programming", 200);
    });
  });
});
.intro {
  text-align: center;
  display: none;
  font-family: 'Amaranth', sans-serif;
}

.cursor {
  display: inline-block;
  width: 10px;
  height: inherit !important;
}

.cursor>span {
  display: inline-block;
  position: relative;
  top: 2px;
  width: 3px;
  height: 26px;
  margin: 0 0 0 0px;
  background-color: #000;
  animation: blink 1s step-end infinite;
}

@keyframes blink {
  from,
  to {
    opacity: 1;
  }
  50% {
    opacity: 0;
  }
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="intro">
  <h1 class="title"><span id="sayHello"></span><span class="cursor"><span></span></span>
  </h1>
  <h1 class="title"><span id="myName"></span><span class="cursor"><span></span></span>
  </h1>
</div>

Здесь я пытаюсь print две строки текста внутри двух разных <h1> тегов.Для этого я звоню function typeWriter(...) дважды, один раз для каждого <h1>.Я пытаюсь набрать print две строки, одну после завершения предыдущей, т. Е. Вывести Hello !! при первом вызове и после его завершения, затем вывести I'm Learning Programming во второй строке, но этого не происходит.Проблема в том, что они выполняются вместе.

При дальнейшем поиске решения я нашел этот вопрос JavaScript: выполните асинхронную функцию по очереди и следуйте ответу, данному @ DavidHedlund, но у меня это не работает.Извините, если я ошибаюсь.Пожалуйста, взгляните на скрипку, которую я попробовал из @ DavidHedlund ответа.В этом случае печатается только Hello !!.

$(document).ready(function() {
  function typeWriter(element, msg, speed, index = 0) {
    if (index < msg.length) {
      $(element).html($(element).html() + msg.charAt(index++));
      setTimeout(function() {
        typeWriter(element, msg, speed, index);
      }, speed);
    }
  }

  $('.intro').fadeIn(function() {

    function executeTasks() {
      var tasks = Array.prototype.concat.apply([], arguments);
      var task = tasks.shift();
      task(function() {
        if (tasks.length > 0)
          executeTasks.apply(this, tasks);
      });
    }

    function createTask(param) {
      let element = param[0];
      let msg = param[1];
      let speed = param[2];
      return function(callback) {
        setTimeout(function() {
          if (typeof callback == 'function') typeWriter(element, msg, speed);
        }, 1);
      }
    }
    var t1 = createTask(['#sayHello', "Hello !!", 200]);
    var t2 = createTask(['#myName', "I'm Anshuman Gupta", 200]);
    executeTasks(t1, t2);
  });
});
.intro {
  text-align: center;
  display: none;
  font-family: 'Amaranth', sans-serif;
}

.cursor {
  display: inline-block;
  width: 10px;
  height: inherit !important;
}

.cursor>span {
  display: inline-block;
  position: relative;
  top: 2px;
  width: 3px;
  height: 26px;
  margin: 0 0 0 0px;
  background-color: #000;
  animation: blink 1s step-end infinite;
}

@keyframes blink {
  from,
  to {
    opacity: 1;
  }
  50% {
    opacity: 0;
  }
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="intro">
  <h1 class="title"><span id="sayHello"></span><span class="cursor"><span></span></span>
  </h1>
  <h1 class="title"><span id="myName"></span><span class="cursor"><span></span></span>
  </h1>
</div>

Спасибо !!

Ответы [ 3 ]

0 голосов
/ 07 октября 2018

В качестве альтернативы, вы можете использовать await, если вам это кажется более простым.

$(document).ready(function() {
  function typeWriter(element, msg, speed, index = 0) {
    return new Promise((resolve, reject) => {
      if (index < msg.length) {
        $(element).html($(element).html() + msg.charAt(index++));
        setTimeout(function() {
          typeWriter(element, msg, speed, index).then(resolve).catch(reject);
        }, speed);
      } else {
        resolve();
      }
    });
  }
  
  async function typeStuff() {
    console.log("Hi");
    await typeWriter('#sayHello', "Hello !!", 200);
    await typeWriter('#myName', "I'm learning programming", 200);
  }

  $('.intro').fadeIn(function() {
    typeStuff();
  });
});
.intro {
  text-align: center;
  display: none;
  font-family: 'Amaranth', sans-serif;
}

.cursor {
  display: inline-block;
  width: 10px;
  height: inherit !important;
}

.cursor>span {
  display: inline-block;
  position: relative;
  top: 2px;
  width: 3px;
  height: 26px;
  margin: 0 0 0 0px;
  background-color: #000;
  animation: blink 1s step-end infinite;
}

@keyframes blink {
  from,
  to {
    opacity: 1;
  }
  50% {
    opacity: 0;
  }
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="intro">
  <h1 class="title"><span id="sayHello"></span><span class="cursor"><span></span></span>
  </h1>
  <h1 class="title"><span id="myName"></span><span class="cursor"><span></span></span>
  </h1>
</div>

Объяснение: в своем коде вы позвонили resolve сразу после вызова typeWriter.Проблема в том, что typeWriter не «блокирует», то есть устанавливает тайм-аут для выполнения кода в будущем и немедленно возвращается.Вы можете избежать этого, сделав typeWriter обещание.Затем вы можете использовать await (что чище, но менее поддерживается браузерами) или typeWriter(...).then(function() { /* Do more stuff */ }) (они по сути эквивалентны).

0 голосов
/ 07 октября 2018

Проблема в том, что вы не дожидаетесь завершения функции рекурсии, а затем вызываете функцию разрешения.

 const greet = new Promise(function(resolve, reject) {
  typeWriter('#sayHello', "Hello !!", 200);
  resolve();
});
greet.then(function() {
  typeWriter('#myName', "I'm learning programming", 200);
});

Попробуйте:

const timeout = (speed) => {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
        resolve();
    }, speed);
  });
}

$(document).ready(function() {
async function typeWriter(element, msg, speed, index = 0) {
  if (index < msg.length) {
    $(element).html($(element).html() + msg.charAt(index++));
    await timeout(speed);
    await typeWriter(element, msg, speed, index);
  }
}

$('.intro').fadeIn(function() {
    const greet = new Promise(async function(resolve, reject) {
      await typeWriter('#sayHello', "Hello !!", 200);
      resolve();
    });
    greet.then(function() {
      typeWriter('#myName', "I'm learning programming", 200);
    });
  });
});
0 голосов
/ 07 октября 2018

Итак, что здесь происходит, метод typeWriter() использует setTimeout(), который работает на многопоточной модели (т. Е. setTimeout() не будет блокировать поток, а сразу же вернется).Вот почему метод typeWriter() немедленно возвращается, и поэтому соответствующее обещание разрешается.

Попробуйте этот код

$(document).ready(function() {
    function typeWriter(element, msg, speed) {
        return new Promise (function (resolve, reject) {
            var recursive = function (element, msg, speed, index) {
                if (index < msg.length) {
                    $(element).html($(element).html() + msg.charAt(index++));
                    setTimeout(function() {
                        recursive(element, msg, speed, index);
                    }, speed)
                } else {
                    resolve();
                }
            }
            recursive(element, msg, speed, 0)
        })
        }

    $('.intro').fadeIn(function() {
        typeWriter('#sayHello', "Hello !!", 200).then(function() {
            return typeWriter('#myName', "I'm learning programming", 200);
        });
    });
})
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...