2

I have few functions which should be executed one by one in loop and with delay. Here is the code I have:

function func1() {
  for (var i = 0; i < 3; i++) {
    func2().then(); // await in loop until func2() completed       
  }
}

function func2() {
  return new Promise(succes) {
    for (var i = 0; i < 10; i++) {
      function3().then(); //wait untill function3 and then continue looping
    }
    success();
  }
}

function function3() {
  return new Promise(function(ready) {
    setTimeout(function() {
      // do some stuff
      ready();
    }, 2000);
  });
}

But it doesn't work. What I should change?

nem035
  • 34,790
  • 6
  • 87
  • 99
dantey89
  • 2,167
  • 24
  • 37
  • Check out sync and async operation difference. http://stackoverflow.com/questions/16336367/what-is-the-difference-between-synchronous-and-asynchronous-programming-in-node – Mykola Borysyuk Jan 13 '17 at 14:34
  • 2
    Promises are not synchronous – epascarello Jan 13 '17 at 14:34
  • I thought that then() is something similar with .net await operator. But it is not – dantey89 Jan 13 '17 at 14:36
  • Also `.then()` is used to attach a callback to a promise. Using `.then()` on its own with no parameters does nothing but return the same promise again. See: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/then – gen_Eric Jan 13 '17 at 15:07

3 Answers3

4

I think what you intended to use is ES8's (ES2017) async/await construct:

async function func1() {
  for (var i = 0; i < 3; i++) {
    console.log(`func1 waiting for func2 #${i + 1}`);
    await func2(); // await in loop until func2() completed 
    console.log(`Finished iteration ${i} for func1`);
  }
}

async function func2() {
  console.log('Started func2');
  for (var i = 0; i < 10; i++) {
    console.log(`func2 waiting for func3 #${i + 1}`);
    await function3(); //wait untill function3 and then continue looping
  }
}

function function3() {
  return new Promise(resolve => setTimeout(resolve, 1000));
}

func1().then(() => console.log('finished'));

For a wider browser support, you can use Babel

.

nem035
  • 34,790
  • 6
  • 87
  • 99
  • Yes, this is what I really looking for. How can I be sure tat this code 100% will be executed on user's side? I mean, not all browsers supports EC7. – dantey89 Jan 13 '17 at 15:41
  • 1
    You can use [Babel](http://babeljs.io/) to transpile your code to ES5 when deploying – nem035 Jan 13 '17 at 15:43
  • `async/await` is not part of ES7 (ES2016). It will be part of this year's release, ES2017. – Felix Kling Jan 13 '17 at 15:53
  • @FelixKling you're right, I forgot that ES7 was a tiny release of the exponentiation operator and I think one of the `includes` methods. Corrected my answer. – nem035 Jan 13 '17 at 16:11
0

I don't know it's a the best solution, but it is some way and i think this easy to implement.

function func1(i){
     i++;
     return new Promise(function(ready){
            setTimeout(function(){  
                func2(i);
                ready(i);           
            }, 1000); 
    });
}

function func2(i = 0){
  if(i < 10){
    func1(i).then((test) => {
      console.log(test);
    })
  } else {
    return false;
  }
}
func2();
Piotr Białek
  • 2,569
  • 1
  • 17
  • 26
-1

You can use jQuery's .each() , it's synchronous so the next loop won't fire until the previous ends. You can also add callbacks but they are not really needed here.

Vortic
  • 75
  • 1
  • 8
  • `func2().then();` will create a new Promise, then move onto the next loop iteration. `.each` just uses `for` under the hood. – gen_Eric Jan 13 '17 at 15:04