1

Please Assist.

I need to wait for an operation to finish before executing it again in 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.

Output should append text in a "textarea" using settimeout. It needs to wait for that to finish then starts typing the next text at whatever random index of the "arrayofrandomtext " array is called. Later on the "ProcessText(someint)" may still be called based on a keystroke etc.

  • The existing text must be appended, not replaced at 0 instead appending i.e 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);

 }
}

1
  • what is this someControl.value. Commented Nov 4, 2015 at 5:42

2 Answers 2

1

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. 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. First modify the log function to take a callback as a parameter.

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. Here f is a 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)
 });
Sign up to request clarification or add additional context in comments.

Comments

1

Try creating an array of text values , using Array.prototype.slice() to create copy of initial array of text values ; Array.prototype.shift() to set text parameter for next_letter ; if array has .length after inital call to next_letter , recursively call 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>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.