0

basically, I have three functions, and what I want is to run all theses three functions in sequence (synchronous) and each function wait for the previous function finish. I've put the timeout within the functions to simulate a time execution, I don't know if this works. My code is.

//my three functions...
function wait1() {
    setTimeout(function(){
        console.log('hello, this is the function 1');
        return 'ok';
    },2000)
}

function wait2() {
    setTimeout(function(){
        console.log('hello, this is the function 2');
        return 'ok';
    },2000)
}

function wait3() {
    setTimeout(function(){
        console.log('hello, this is the function 3');
        return 'ok';
    },2000)
}

var tasks = [wait1,wait2,wait3];
var counter = 0;

function iterateTasks(tasks) {
    runSequence(tasks[counter], function(){
        counter++;
        if(counter < tasks.length) {
            iterateTasks(tasks);
        }
    });
}

//@params func   received function
//@params cb   received callback function
function runSequence(func,cb) {
    var timeout = 0;
    var tmr = setInterval(function(){
        if(func() === 'ok' || timeout === 5000) {
            console.log('OK, func = ', func);
            cb();
            clearInterval(tmr); 
            timeout = 0;
        }
        timeout += 500;
    },500);
}

//start program...
iterateTasks(tasks);

Appreciate any help!

Pablo Darde
  • 5,844
  • 10
  • 37
  • 55
  • 2
    What's the question? – Pointy Sep 07 '16 at 14:46
  • Do you want them to run after the timeout of each function is done? – ave4496 Sep 07 '16 at 14:47
  • 2
    The best way is to promisify setTimeout and use promises control sequencing. – danh Sep 07 '16 at 14:47
  • @Pointy by the code I guess it doesn't work – pwolaq Sep 07 '16 at 14:47
  • 3
    You cannot `return` out of an async method. The calling code will not wait. You should look into callbacks or even better promises. – ste2425 Sep 07 '16 at 14:47
  • 3
    Use `promises`, ES5 doesn't have this though, You need to use libraries like `jQuery` or framework like `AngularJS` – David R Sep 07 '16 at 14:47
  • Possible duplicate of [javascript function wait until another function to finish](http://stackoverflow.com/questions/24655851/javascript-function-wait-until-another-function-to-finish) – André Dion Sep 07 '16 at 14:49
  • Add callback to each function that will be executed after function finish passing return value, if you return value from setTimeout callback it will be lost. – jcubic Sep 07 '16 at 14:49
  • @DavidR - there are far lighter libraries than angular and jquery for Promises - my favourites include Pinky Swear and then/promise – Jaromanda X Sep 07 '16 at 14:50
  • @Pointy - no, what's on second – Jaromanda X Sep 07 '16 at 14:51
  • @JaromandaX Agree with you! However as we use jQuery a lot in our project that usually comes in my mind first! :-) – David R Sep 07 '16 at 14:52
  • @DavidR - until recently, Promises in jquery were not Promise/A+ - but yeah, I get where you're coming from, if you already use jquery, then why not :p – Jaromanda X Sep 07 '16 at 14:54
  • Sorry guys, let me explain better. I want each function (not timeout) only be called after the previously function has finished. i.e. wait2() only runs after wait1() finish. I've used timeouts to simulate a time in order the next function wait, but I don't know if it works. – Pablo Darde Sep 07 '16 at 17:23

2 Answers2

0

Try to add callback to each function:

//my three functions...
function wait1(callback) {
    setTimeout(function(){
        console.log('hello, this is the function 1');
        callback('ok');
    },2000)
}

function wait2(callback) {
    setTimeout(function(){
        console.log('hello, this is the function 2');
        callback('ok');
    },2000)
}

function wait3(callback) {
    setTimeout(function(){
        console.log('hello, this is the function 3');
        callback('ok');
    },2000)
}

var tasks = [wait1,wait2,wait3];
var counter = 0;

function iterateTasks(tasks, callback) {
    setTimeout(function req(){
        tasks[counter++](function(value) {
            if (counter == tasks.length) {
                if (typeof callback == 'function') {
                    callback();
                }
            } else if (value === 'ok') {
                setTimeout(req, 500);
            }
        });
    }, 500);
}

//start program...
iterateTasks(tasks);
jcubic
  • 61,973
  • 54
  • 229
  • 402
-1

Promises are fine but you might as well do this job with generators' lazy evaluation. Let's see how it might be implemented.

function* runner(functions,text){
  var val = text;
  for (var fun of functions) {
   val = yield fun(val);
  }
}

function wait1(t) {
    setTimeout(function(){
                 console.log(t + "1");
                 it.next(t);
               },2000);
}

function wait2(t) {
    setTimeout(function(){
                 console.log(t + "2");
                 it.next(t);
               },2000);
}

function wait3(t) {
    setTimeout(function(){
                 console.log(t + "3");
                 it.next(t);
               },2000);
}

var tasks = [wait1,wait2,wait3],
       it = runner(tasks, "Hello this is function #");
it.next();  // start the engine...!
Redu
  • 25,060
  • 6
  • 56
  • 76
  • While shiny new things are fun ... it's easy to polyfill Promises that existed non natively pre ES2015 ... it's not possible to polyfill ES2017 generators – Jaromanda X Sep 07 '16 at 15:32
  • @Jaromanda X Generators are part of ES6, so do promises. There are some changes in ES7 ([as mentioned at MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function*#Specifications) they will no longer have constructors) but this doesn't change the fact they are perfectly fine to use in a wide variety of environments which are compatible with ES6. – Redu Sep 07 '16 at 15:59
  • I just don't get the point of down voting this answer since it gives an idea of handling the job in a proper way not mentioned herein before. – Redu Sep 07 '16 at 15:59
  • we, as website developer, still have a lot of internet explorer users to support - yes, it makes me want to tear my pubic hair out, but it's a fact. My comment was not a criticism of the code or the answer, the comment was merely to point out that there is no way to get this working in such browsers (and yes, I exaggerated with ES2017, I'm surprised they are actually part of ES2015, I thought they were ES2016 :p – Jaromanda X Sep 08 '16 at 13:25