javascript - setTimeout Function with Dynamic Duration -
i have settimeout function iterates on values:
var content = ['one', 'two', 'three', 'four', 'five'] var duration = ['10000', '10000', '20000', '10000', '30000'] (i = 0; < content.length; i++) { settimeout(function () { alert("hi") }, duration[i]) }
however, duration not dynamic. i've attempted parseint(duration[i])
doesn't work either. doing wrong here?
-------------clarification-----------------:
as understand it, settimeout() method "calls function or evaluates expression after specified number of milliseconds"1. abstract code above quite suggests (though may take more brief glance determine), each item in content
array, there set of operations performed. each operation associated duration of time, in milliseconds, current operation should wait until next operation begins.
in example above, upon initiating function, initial wait duration, 10000 milliseconds, first item in duration array, seems called expected. however, subsequent operations not wait duration specified respective value in duration array.
as poster mentioned, want each timeout start end of last one. use suggested "recursive" approach, promises result in more readable code. first, we'll write wait
routine returns promise resolves in number of milliseconds:
function wait(n) { return new promise(function(resolve) { settimeout( resolve, n); }); }
now can rewrite loop follows:
var promise = promise.resolve(); (i = 0; < content.length; i++) { promise = promise . then(function() { return wait(duration[i]; }); }
we need promise.resolve()
kick things off promise resolved. way, bonus, @ end of loop have promise entire chain of timeouts having completed, can use next.
it turns out same as
duration.reduce( function(promise, ms) { return promise . then(function() { return wait(ms); }); }, promise.resolve() );
if don't know reduce
, it's worth learning.
but imagine how nice skip this, , have instead of setting timeout, waits right there. turns out can in fact this, using async
functions:
async function wait_series(duration) { ^^^^^ (i = 0; < content.length; i++) { await wait(duration[i]); ^^^^^ } }
async functions require using appropriate transpiler, such babel, appropriate flags.
if don't have or want use babel, have access generators, use library co
turn generator (function*
) asynchronous function, yield
want wait:
function wait_series(duration) { co(function *() { ^^ (i = 0; < content.length; i++) { yield wait(duration[i]); ^^^^^ } }); }
the advantage of using async functions, or co
-based equivalent, can go writing regular old for
loops used to. allow write asynchronous code synchronous mindset. no longer have think promises (although co
magic under hood using them).
you may seems lot of stuff learn write sequential series of timeouts. actually, promises , async functions easier in end writing timeouts call functions set other timeouts.
recursive solution
if prefer recursive solution, here streamlined version of it, works (by invoking loop
first time via ()
@ end):
function wait_series(duration) { var = duration.length; (function loop() { if (i--) settimeout(loop, duration[i]); })(); ^^ }
Comments
Post a Comment