简体   繁体   English

在重新运行它之前,请等待使用settimeout的函数在javascript中完成

[英]Wait for function that makes use of settimeout to complete in javascript before rerunning it

Please Assist. 请协助。

I need to wait for an operation to finish before executing it again in javascript. 我需要wait操作完成才能在javascript中再次执行它。 These operations may be run at different times. 这些操作可能在不同的时间运行。 Not all at once. 并非一次全部。 I have a problem with running 2 operations at once since they execute at the same time. 我一次运行2个操作有一个问题,因为它们同时执行。

Output should append text in a "textarea" using settimeout . 输出应使用settimeout在“ textarea”中附加文本。 It needs to wait for that to finish then starts typing the next text at whatever random index of the "arrayofrandomtext " array is called. 它需要等待完成,然后在调用“ arrayofrandomtext”数组的任意索引处开始键入下一个文本。 Later on the "ProcessText(someint)" may still be called based on a keystroke etc. 稍后仍然可以基于按键等调用“ ProcessText(someint)”。

  • The existing text must be appended, not replaced at 0 instead appending ie Hello World. 必须添加现有文本,而不是将其替换为0,而是添加即Hello World。 Something else.... 还有别的...

 var index=0; var arrayofrandomtext = ["Hello World","something else", "other stuff"]; function ProcessText(someint){ //These may run together next_letter(arrayofrandomtext[someint]); //wait to complete and rerun it with other text next_letter(arrayofrandomtext[someint]); //later on if the user hits a key this may run only next_letter(arrayofrandomtext[someint]); } function next_letter(text){ if (index <= text.length) { someControl.value = text.substr(0, index++); setTimeout(function () { next_letter(text); }, 50); } } 

Try creating an array of text values , using Array.prototype.slice() to create copy of initial array of text values ; 尝试创建文本值数组,使用Array.prototype.slice()创建文本值初始数组的副本; Array.prototype.shift() to set text parameter for next_letter ; Array.prototype.shift()设置next_letter文本参数; if array has .length after inital call to next_letter , recursively call ProcessText 如果数组在对next_letter初始调用之后具有.length ,则递归调用ProcessText

 var arr = ["Hello...", "Some other text"], copy = arr.slice(), button = document.querySelector("input") someControl = document.querySelector("textarea"), index = 0; function ProcessText() { next_letter(copy.shift()) } function next_letter(text) { if (index <= text.length) { someControl.value = text.substr(0, index++); setTimeout(function() { next_letter(text); }, 50); } else { index = 0; if (!!copy.length) { ProcessText() } else { copy = arr.slice(); } } } button.onclick = ProcessText; 
 <input type="button" value="click" /><br /> <textarea></textarea> 

First, you already have done this - but I'd like a working version for demonstration. 首先,您已经完成了此操作-但我想要一个工作版本进行演示。 You can write a recursive function, which calls settimeout on itself after it has finished. 您可以编写一个递归函数,该函数在完成后对其自身调用settimeout。 For example, given a function which logs out each letter of a string. 例如,给定一个注销字符串中每个字母的函数。

var log = function(text, index, duration) {
  console.log(text[index]);

  if (index < text.length - 1) {
    setTimeout(function() {
      log(text, index + 1, duration);
    }, duration);
  }
};

log("Hello There", 0, 1000);
log("Nice to see You", 0, 1000);

Now of course, if you run this code, the second log function will not wait for the first. 当然,现在,如果您运行此代码,第二个日志功能将不会等待第一个。 You can use Promises and/or Callbacks to perform async control flow. 您可以使用Promises和/或Callbacks执行异步控制流。 First modify the log function to take a callback as a parameter. 首先修改log函数以将回调作为参数。

var logCB = function(text, index, duration, cb) {
  console.log(text[index]);

  if (index < text.length - 1) {
    setTimeout(function() {
      logCB(text, index + 1, duration, cb);
    }, duration);
  } else {
    cb();  //execute callback
  }
};

Now if you pass your second function (wrapped in another function to delay execution). 现在,如果您传递了第二个函数(包装在另一个函数中以延迟执行)。 as a parameter to your first, it will execute after it has finished. 作为您的第一个参数,它将在完成后执行。

var cb = function() {
  logCB("Nice to see you", 0, 1000);
};

logCB("Hello, World!", 0, 1000, cb);

While this works, it can become unwieldy for multiple nesting. 虽然这可行,但对于多个嵌套来说却变得笨拙。 A better solution is to use a promise - you only need to wrap your logCB in another function. 更好的解决方案是使用promise-您只需要将logCB包装到另一个函数中即可。 Here f is a logCB. 这里f是一个logCB。

var promiseLog = function(f, text, delay) {
  return new Promise(function(resolve, reject) {
     f(text, 0, delay, resolve);
  });
};

Then ... we can chain them together to wait for completion with .. Then. 然后...我们可以将它们链接在一起,以..然后等待完成。

promiseLog(logCB, "Hello World", 1000)
 .then(function() {
   return promiseLog(logCB, "Hey There", 1000)
 });

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM