How to roll over this recursive function

Below is a simple recursive function that takes length and reduces it with setTimeout. Once the length is <=0, this was done.

How can I write this function (in pure JavaScript) so that I can use it like this:

animate(999).then(...)

const animate = length => {
  console.log(length)
  length -= 10
  if (length <= 0) {
    length = 0
    return
  }
  setTimeout(() => {animate(length)}, 10)
}

animate(999)
Run codeHide result

Update:

This is what I tried. The problem I am facing is that it seems that it is resolveeither not being called, or being called by another promise.

const animate = length => {
  return new Promise((resolve, reject) => {
    console.log(length)
    length -= 10
    if (length <= 0) {
      length = 0
      resolve(true)
      return // without this the function runs forever
    }
    setTimeout(() => {animate(length)}, 10)
  })
}

animate(999).then(result => console.log(result))
Run codeHide result

** Working update (but do not understand) **

const animate = length => {
  return new Promise((resolve, reject) => {
    console.log(length)
    length -= 10
    if (length <= 0) {
      length = 0
      return resolve(true)
    }
    setTimeout(() => {resolve(animate(length))}, 10)
  })
}

animate(999).then(result => console.log(result))
Run codeHide result
+4
source share
4 answers

setTimeout(() => {animate(length)}, 10) , animate, , ( , " " - , ).

, , , , setTimeout:

function wait(t) {
    return new Promise(resolve => {
        setTimeout(resolve, t);
    });
}

, :

const animate = length => {
  console.log(length)
  length -= 10
  if (length <= 0) {
    length = 0
    return Promise.resolve()
  }
  return wait(10).then(() => {
    return animate(length)
  })
}
+4

Promise , , resolve reject , Promise setTimeout (, if (length <= 0)).

Promise((resolve, reject) , .

, resolve, reject .

+2

Just for fun you can do it. You do not have to . Code not available.

const animate = (length, resolve) => {
  var promise;
  
  if (!resolve) {
    promise = new Promise((newResolve) => {
      resolve = newResolve;
    });
  }
  
  console.log(length);
  length -= 10;
  
  if (length <= 0) {
    length = 0;
    resolve(true);
    return promise;
  }
  
  setTimeout(() => {animate(length, resolve)}, 10);
  
  return promise;
}

animate(999).then(result => console.log(result))
Run codeHide result
+2
source

This is a great job for async/ await:

let wait = ms => new Promise(resolve => setTimeout(resolve, ms));

const animate = async length => {
  for (; length > 0; length -= 10) {
    console.log(length);
    await wait(10);
  }
  return 0;
}

animate(999).then(() => console.log("Done!"));
Run codeHide result
+1
source

Source: https://habr.com/ru/post/1672292/


All Articles