等待以前的异步功能完成

时间:2016-03-13 15:04:05

标签: javascript jquery

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

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

我已经尝试了很多方法,但是我得到的最接近的是调用函数,每个方法之间有一个延迟,当我需要完成函数的时间时,这会非常烦人。

最近的

Call requires permission which may be rejected by the user

然后我必须像这样打电话给他们

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);
}

Fiddle

2 个答案:

答案 0 :(得分:2)

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

&#13;
&#13;
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');
});
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<div id="out">
  <div>
&#13;
&#13;
&#13;

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

答案 1 :(得分:2)

使用本机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 promises或者至少使用polyfill:https://github.com/stefanpenner/es6-promise