等待上一个异步函数完成

Waiting for previous async function to complete

本文关键字:函数 异步 上一个 等待      更新时间:2023-09-26

>我在我的项目中添加了一个函数,该函数输出字符之间有超时的句子,效果很好。问题是JS异步执行所有函数调用,而我希望它等待上一句完成,然后再开始下一句。

我希望这是一个可链接的jQuery函数,最终与.delay一起使用。我有很多句子要打印,所以嵌套回调会很乏味。

我已经尝试了许多方法,但我最接近的方法是在每种方法之间都有延迟的情况下调用函数,当我必须对函数进行计时时,这会很烦人。

这是最新的

var printMsg = function(msg) {
  var index = 0;
  var out = $('#out').append('<pre></pre>');
  var msgOut = setInterval(function() {
    out.children(':last-child').append(msg[index++]);
    if (index >= msg.length) {
      clearInterval(msgOut);
    };
  }, 150);
}

那我必须这样称呼他们

var timeout = 8000;
printMsg('Lorem ipsum Laboris Duis cupidatat ut id enim nisi');
setTimeout(function() {
  printMsg('Lorem ipsum Laboris Duis cupidatat ut id enim nisi');
}, timeout);
timeout += 8000;
setTimeout(function() {
  printMsg('Lorem ipsum Laboris Duis cupidatat ut id enim nisi');
}, timeout);

小提琴

使用本机 ES6 承诺和链接的工作示例: https://jsfiddle.net/5hro5zq1/

var printMsg = function(msg) {
  var promise = new Promise(function(resolve, reject){
    var index = 0;
    var out = $('#out').append('<pre></pre>');
    var msgOut = setInterval(function() {
      out.children(':last-child').append(msg[index++]);
      if (index >= msg.length) {
        clearInterval(msgOut);
        resolve();
      };
    }, 150);
  });
  return promise;
}
function printMessages(messages){
  if(messages.length){
    printMsg(messages[0])
      .then(function(){
        printMessages(messages.slice(1, messages.length))
      });
  }
}
var messages = [
  'This is the first sentence.',
  'This is another sentence.',
  'We can do this all day long...'
];
printMessages(messages);

如果你想要这样的东西,你可能想使用jQuery承诺,或者至少使用polyfill:https://github.com/stefanpenner/es6-promise

使用递归函数将是最佳选择。您将可以更好地控制执行。因为您只能在完成当前函数后使用如下所示的代码执行下一个函数。

var msg = [
  '1 Lorem ipsum Laboris Duis cupidatat ut id enim nisi',
  '2 Lorem ipsum Laboris Duis cupidatat ut id enim nisi',
  '3 Lorem ipsum Laboris Duis cupidatat ut id enim nisi',
  '4 Lorem ipsum Laboris Duis cupidatat ut id enim nisi'
];
var printMsg = function(index, callback) {
  if (msg.length > index) { // if all messages are not yet loaded.
    var out = $('#out').append('<pre></pre>');
    var charIndex = 0;
    var interval = setInterval(function() {
      out.children(':last-child').append(msg[index][charIndex++]);
      if (charIndex >= msg[index].length) {
        clearInterval(interval);
        // resolve();
        printMsg(++index, callback); //increment the index and pass the same callback
        //Recursive function call.
      }
    }, 150);
  } else {
    callback(); // all the messages are loaded
  }
}
//trigger the chain reaction by passing the first message index
printMsg(0, function() {
  alert('all the messages are printed!! and Synchronously too');
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="out">
  <div>

注意:回调在上述解决方案中没有用处。它仅用于在加载消息时传入自定义函数,如果函数printMsg在多个地方使用,这将是最好的方法。否则,您可能必须将逻辑放在printMsg的 else 部分。