等待先前的异步功能完成[重复]

Posted

技术标签:

【中文标题】等待先前的异步功能完成[重复]【英文标题】:Waiting for previous async function to complete [duplicate] 【发布时间】:2016-06-28 13:31:55 【问题描述】:

我在我的项目中添加了一个函数,可以输出字符之间有超时的句子,效果很好。问题是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);

Fiddle

【问题讨论】:

是什么阻止了你使用回调? 【参考方案1】:

使用原生 ES6 Promise 和链接的工作示例: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

【讨论】:

【参考方案2】:

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

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 部分。

【讨论】:

谢谢,但我需要它来打印每个字符之间的超时时间 您可以将超时设置在 printMsg 中,对吗?比如将完整的逻辑包装到区间中 @Intern 检查我更新的答案。每条消息打印之间有 2 秒的延迟。 这是每个句子之间的超时,而不是每个字符之间的超时。查看@dannyjolie 的示例 @Intern 好的,我看错了 OP,检查我新编辑的解决方案。

以上是关于等待先前的异步功能完成[重复]的主要内容,如果未能解决你的问题,请参考以下文章

每个数组元素的异步调用并等待完成[重复]

chrome扩展-sendResponse不等待异步功能[重复]

功能推送的异步/等待不起作用[重复]

如何快速使用异步函数?完成处理程序[重复]

无法理解异步和等待的需求[重复]

Promise.all()函数中的JS“等待仅在异步函数中有效”[重复]