1

Need to create a sequence of functions stored in an array. Need them to be executed every 400ms. Did it by setting 500 setTimeout(function(){})'s. Somehow learned that should do it by creating it dynamically. Have the functions ready, but missing the timeouts to make it a nice animation

Here is the part where I think I have to set the timeout's in:

function start() {
    mylist.name = this.className;
    mylist.identifier = 'port'+parseFloat(this.id);
    mylist.number = parseFloat(this.id);
    console.log(mylist.number);
    for (var x in todo) {
        todo[x]();
    }
}

And here is the array with the functions. Thank you

ps: sorry for bad english, made in Germany :)

todo = [

function computer1() {
    $('.'+mylist.name+':eq(1)').css({'background-color': 'chartreuse'});
},
function kabel1() {
    $('.'+mylist.name+':eq(0)').css({'border-bottom-color': 'chartreuse'});
},
function port1() {
    $('#'+mylist.identifier).css({'background-color': 'chartreuse'});
},
function port2() {
    for (var x=0;x<ports;x++) {
        $('#port'+(x+1)).css({'background-color': 'blue'});
        if (x===(mylist.number-1)) {
            $('#port'+(x+1)).css({'background-color': 'chartreuse'});
        }       
    }
},
function kabel2() {
    for (var x=0;x<ports;x++) {
        $('#portugal'+(x+1)+':eq(0)').css({'border-bottom-color': 'blue'});
        if (x===(mylist.number-1)) {
            $('#portugal'+(x+1)+':eq(0)').css({'border-bottom-color': 'chartreuse'});
        }       
    }
},
function device2() {
    for (var x=0;x<ports;x++) {
        $('#'+(x+1)+'device').css({'background-color': 'blue'});
        if (x===(mylist.number-1)) {
            $('#'+(x+1)+'device').css({'background-color': 'chartreuse'});
        }
    }
},
function device3() {
    for (var x=0;x<ports;x++) {
        if (document.getElementById('info').textContent==document.getElementById((x+1)+'device').className) {
            var hammer = document.getElementById((x+1)+'device').getAttribute('class');
            $('.'+hammer+':eq(1)').css({'background-color': 'red'});
        }
    }
},
function mehr() {

}]
8
  • 1
    Is it in any way possible you could get an executable version of that? Also it is quite a lot of code -> if possible be more specific as this will understandably "turn off" some people ^^ Please provide minimal example code :) Commented Oct 1, 2018 at 14:11
  • I think you need only the first example part of code to help me, but i dont know maybe you need the complete code for context... Commented Oct 1, 2018 at 14:15
  • I'm not quite sure what you want to do... create an animation on a canvas... but with multiple functions? Or just an "animation" on an div element? Commented Oct 1, 2018 at 14:17
  • No, I want to execute every function every 400ms so every function combined sums up in an animation. Commented Oct 1, 2018 at 14:18
  • Because when I start the programm without timeouts, all functions are executed at the same time Commented Oct 1, 2018 at 14:19

3 Answers 3

1

Something like that?

let startTime = new Date().getTime();
let functions = [
    ()=>console.log("f0: " + (new Date().getTime() - startTime) + " ms passed"),
    ()=>console.log("f1: " + (new Date().getTime() - startTime) + " ms passed"),
    ()=>console.log("f2: " + (new Date().getTime() - startTime) + " ms passed"),
    ()=>console.log("f3: " + (new Date().getTime() - startTime) + " ms passed"),
    ()=>console.log("f4: " + (new Date().getTime() - startTime) + " ms passed"),
]

let i = 0;
setInterval(() => {
  functions[i]();
  i++;
  if(i > functions.length - 1) i = 0;
}, 400);

If it worked always smash the accept button ;)

Sign up to request clarification or add additional context in comments.

Comments

0

I'm not in favor of changing the array and modifying synchronous function. Thus changing for loop.

// Created variable using let to over come closure
for (let x in todo) {
    setTimeout( ()=> {
        todo[x]();
    }, (x+1)*400);
}

Comments

0

You can avoid creating unnecessary closures or computing specific timeouts

const delay = (ms, x) =>
  new Promise (r => setTimeout (r, ms, x))
  
const funcs =
  [ () => console.log (1)
  , () => console.log (2)
  , () => console.log (3)
  ]
  
const forEachDelay = async (ms, [ f = () => {}, ...fs ]) =>
  fs.length === 0
    ? f ()
    : delay (ms, f ()) .then (() => forEachDelay (ms, fs))
    
forEachDelay (1000, funcs)
// 1
// (1000 ms later...) 2
// (1000 ms later...) 3

An advantage of using async is we get a Promise back and we know when the entire sequence is done –

forEachDelay (1000, funcs) .then (() => console.log ('done'), console.error)
// 1
// (1000 ms later...) 2
// (1000 ms later...) 3
// done

Promise is an effective data type because it allows you to combine smaller steps into one big-picture step.

Above we write forEachDelay using a functional expression, but we could also use an imperative-style for loop combined with the powerful await syntax –

const delay = (ms, x) =>
  new Promise (r => setTimeout (r, ms, x))
  
const funcs =
  [ () => console.log (1)
  , () => console.log (2)
  , () => console.log (3)
  ]
  
const forEachDelay = async (ms, fs = []) =>
{ for (const f of fs)
    await delay (ms, f ())
}
    
forEachDelay (1000, funcs) .then (() => console.log ('done'), console.error)
// 1
// (1000 ms later...) 2
// (1000 ms later...) 3
// done

3 Comments

You shouldn't make the function async if you're not awaiting anything.
async is used here to guarantee the return of a Promise – otherwise forEachDelay (1000, [ () => 1 ]) .then (...) fails because 1 is not a Promise and has no then
Just use Promise.resolve(f()) then for the base case.

Your Answer

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