Settimeout not returning instantly - javascript

I was practicing with callback functions and this question is one I can't seem to figure out.
function foo () {
var data = 10;
bar(function (players) {
data = players;
});
return data;
}
function bar (callback) {
setTimeout(callback, 0);
}
var result = foo();
I expected result to be undefined since data = players and there is nothing passed in as players. Since the setTimeout function uses 0 as the delay, shouldn't it run first, and then return data? I looked at the MDN page and there seems to be information on throttling for nested timeouts to >=4ms. Does this also apply in this case?

Since the setTimeout function uses 0 as the delay, shouldn't it run first, and then return data?
No, even with a delay of 0, the callback passed to setTimeout is scheduled to run in the next tick of the event loop.
In other words, the callback is guaranteed to be executed after the current execution ran to completion.

Related

How do you debounce a function after the first call?

I am trying to make a function similar to debounce, except I want the debounced function to be called immediately after the first call and all calls after the first call within the debounce time limit to be debounced. For example, if the function is hooked up to a button, and you rapidly and repeatedly click it 10 times, the function gets called on the first press and gets called a second time after x milliseconds have passed since the tenth press.
Pure JavaScript processing:
Requiring a repeated call within the "debounce" period to be called in addition to the first call adds a complication that can be addressed using a timer in addition to timestamps to make immediate calls if possible.
However, because calls to a function may be delayed, it is not always possible to return a value from the function to the caller in real time.
The following concept code
calls the process "lock" in the sense of locking out calls in a predefined way.
returns undefined to all calls without implementing call backs to allow a caller to tell if its call was actioned or not, or to retrieve a return value;
When a call is made after a lockout period within which addition call attempts were made, the actual arguments used are to place a delayed call are those supplied by the most recent call attempt.
function CallLock( toCall, lockout) {
let argv;
let lastCall = 0;
let timer = 0;
function recall() {
timer = 0;
lastCall = Date.now();
toCall(...argv);
}
return function( ...args) {
let now = Date.now();
if(timer == 0) {
if( now >= lastCall+lockout) {
lastCall = now;
toCall( ...args);
}
else {
argv = args;
timer = setTimeout(recall, lastCall+lockout - now);
}
}
else {
argv = args; // use most recent arguments
}
}
}
// test CallLock
let start;
function demo( msg) {
console.log( "demo('%s') called. Time is %sms after start", msg, Date.now() - start);
}
let lockDemo = CallLock( demo, 1000); // 1 second lockout
start = Date.now();
lockDemo("call 1");
setTimeout( lockDemo, 200, "call 2");
setTimeout( lockDemo, 400, "call 3");
setTimeout( lockDemo, 1800, "call 4");
Test code uses a 1 second lockout time. Note that timer delays are inexact and Date.now() rounds to the nearest millisecond. The expected results are
call 1 is made synchronously and will show a start time of 0 or 1ms.
call 2 is never actioned - its arguments are not used.
call 3 is actioned, but delayed until shortly after the first call lockout
call 4 is actioned, but also delayed because the lockout period from when call 3 was actioned is still in effect.
Sounds like throttle. check this article for difference between throttling and debouncing. if throttle isn't what you need, then you should implement what you need from scratch (and adding more explanation for the details).
Edit:
So, Yes, It is not throttle; It is debounce with invocation on leading edge in lodash;
_.debounce(yourCallback, 100, {
'leading': true
})
I would suggest don't go for debounce. The older debouncing technique relies on setTimeout which is not perfect. Instead try to make use requestAnimationFrame which has in built support for the next trigger for Dom visual states change.

Why and when to use process.nextTick?

Below is the code present in "practise01.js" file,
function fn(name){
return f;
function f(){
var n = name;
console.log("Next TICK "+n+", ");
}
}
function myTimeout(time,msg){
setTimeout(function(){
console.log("TIMEOUT "+msg);
},time);
}
process.nextTick(fn("ONE"));
myTimeout(500,"AFTER-ONE");
process.nextTick(fn("TWO"));
myTimeout(500,"AFTER-TWO");
process.nextTick(fn("THREE"));
myTimeout(500,"AFTER-THREE");
process.nextTick(fn("FOUR"));
The output from running above code is
rahul#rahul:~/myPractise/PlainNodeJSPractise01/Process$ node practise01.js
Next TICK ONE,
Next TICK TWO,
Next TICK THREE,
Next TICK FOUR,
TIMEOUT AFTER-ONE
TIMEOUT AFTER-TWO
TIMEOUT AFTER-THREE
Now I wrote the code without using process.nextTick, in "practise02.js", as follows,
function myTimeout(time,msg){
setTimeout(function(){
console.log("TIMEOUT "+msg);
},time);
}
function fn(name){
return f;
function f(){
var n = name;
console.log("Next TICK "+n+", ");
}
}
fn("ONE")();
myTimeout(500,"AFTER-ONE");
fn("TWO")();
myTimeout(500,"AFTER-TWO");
fn("THREE")();
myTimeout(500,"AFTER-THREE");
fn("FOUR")();
after running the above code the output is
rahul#rahul:~/myPractise/PlainNodeJSPractise01/Process$ node practise02.js
Next TICK ONE,
Next TICK TWO,
Next TICK THREE,
Next TICK FOUR,
TIMEOUT AFTER-ONE
TIMEOUT AFTER-TWO
TIMEOUT AFTER-THREE
If you see both the outputs are same.
So in which case I need to go with process.nextTick ?
When I tried to read more, what I came to understand is If I need to execute some function immediately when the eventloop is empty than go for "process.nextTick".
So how does its different from my second approach.
Please explain me or give me some pointers
The node documentation is actually pretty good in explaining when and why using nextTick:
https://nodejs.org/api/process.html#process_process_nexttick_callback_args
What it does:
This is not a simple alias to setTimeout(fn, 0), it's much more efficient. It runs before any additional I/O events (including timers) fire in subsequent ticks of the event loop.
and when to use:
This is important when developing APIs in order to give users the opportunity to assign event handlers after an object has been constructed but before any I/O has occurred...
function definitelyAsync(arg, cb) {
if (arg) {
process.nextTick(cb);
return;
}
fs.stat('file', cb);
}
definitelyAsync(true, () => {
foo();
});
bar(); // will now allways be called before foo()
First lets understand the behaviour of process.nextTick()
Eventloop has phases where in each phase different type of async functions get executed.
process.nextTick(callback[, ...args]) is a part of the asynchronous API of nodeJS. But it is not technically part of the event loop.
nextTickQueue will be processed after the current operation is completed, regardless of the current phase of the event loop.
any time we call process.nextTick() in a given phase of eventloop, callback passed to process.nextTick() will be resolved before the event loop continues.
Why we need to use process.nextTick
It is very important for APIs to be either 100% synchronous or 100% asynchronous. Consider this example:
// WARNING! DO NOT USE! BAD UNSAFE HAZARD!
function maybeSync(arg, cb) {
if (arg) {
cb();
return;
}
fs.stat('file', cb);
}
const maybeTrue = Math.random() > 0.5;
maybeSync(maybeTrue, () => {
foo();
});
bar();
It is not clear whether foo() or bar() will be called first.
The following approach is much better:
function definitelyAsync(arg, cb) {
if (arg) {
process.nextTick(cb);
return;
}
fs.stat('file', cb);
}
already #Johannes Merz has mentioned in his answer why it's good to use process.nextTick(callback) rather than setTimeout(callback, 0)
For more refer here
You have your answer in your post where you share your output with us in:
rahul#rahul:~/myPractise/PlainNodeJSPractise01/Process$ node practise02.js
Next TICK ONE,
Next TICK TWO,
Next TICK THREE,
Next TICK FOUR,
TIMEOUT AFTER-ONE
TIMEOUT AFTER-TWO
TIMEOUT AFTER-THRE
If we change your timeout interval from 500 to 0 still same result:
function fn(name){
return f;
function f(){
var n = name;
console.log("Next TICK "+n+", ");
}
}
function myTimeout(time,msg){
setTimeout(function(){
console.log("TIMEOUT "+msg);
},time);
}
process.nextTick(fn("ONE"));
myTimeout(0,"AFTER-ONE");// set timeout to execute in 0 seconds for all
process.nextTick(fn("TWO"));
myTimeout(0,"AFTER-TWO");
process.nextTick(fn("THREE"));
myTimeout(0,"AFTER-THREE");
process.nextTick(fn("FOUR"));
Results
Next TICK ONE,
Next TICK TWO,
Next TICK THREE,
Next TICK FOUR,
TIMEOUT AFTER-ONE
TIMEOUT AFTER-TWO
TIMEOUT AFTER-THREE
when you use process.nextTick you basically ensure that the function that you pass as a parameter will be called immediately in the next tick ie. start of next event loop.So that's why all your function in next tick executes before your timer ie. setTimeout next tick doesn't mean next second it means next loop of the nodejs eventloop. Also next tick ensures that the function you are trying to call is executed asynchronously. And next tick has higher priority than your timers, I/O operations etc queued in the eventloop for execution. You should use nextTick when you want to ensure that your code is executed in next event loop instead of after a specified time. nextTick is more efficient than timers and when you want to ensure the function you call is executed asynchronously . You can find more information on this in nodejs docs

How can I make a function that calls another function every 60 seconds?

I have this function:
isAuthenticated = (): boolean => {
xxx
};
I am using AngularJS and I would like to know how can I make a function such as
keepCheckingAuthentication()
That will call the is Authenticated() function every 60 seconds?
There’s a setInterval function that will call any code with given time interval in ms:
var intervalID = setInterval(function() { console.log('Works!') }, 1000);
Later you can cancel the timer using clearInterval(intervalID).
If isAuthenticated can be modified to actually make a request to call the server in order to check authentication, and can return a promise that resolves or rejects when this is done, then I would do something like
var keepCheckingAuthentication = function() {
return isAuthenticated().catch(angular.noop).then(function(isAuth) {
// Can do something different if isAuth == false
return $timeout(keepCheckingAuthentication, 60 * 1000);
});
});
Note the call to catch. This effectively converts any rejections to a success, so the next then callback runs in every case.
Using something like this rather than $setInterval means there will always be 60 seconds between responses from the server, rather than requests made. On a slower connection, or an overloaded server, this means there is a lower chance of adding to the overloaded connection or server, as you're sure the previous request has finished before sending off another one.
you can probably use $interval function (wrapper of window.setInterval() in AngularJS)?
The documentation of $interval function is here
In your case keepCheckingAuthentication() is the function and you can adjust the other parameters accoding to your needs? Does this help?
example:
$interval(myFunctionAtInterval, 5000) // Scheduled for every 5 seconds, for instance
funtion myFunctionAtInterval() {...}
I tend to avoid setInterval whenever I can, i.e. always (Paul Irish talks about this in this video).
What I do is wrap a setTimeout in a function that recursively calls itself (with a condition that allows me to easily stop, or to let the data decide when it's not needed anymore).
var condition = true;
$scope.count = 1;
function myFunc(){
$scope.count += 1;
}
var timer = function(){
myFunc();
if( condition ){
$timeout(timer, 1000);
}
};
timer();
I am using angular built in $timeout here as it's always suggested.
A demo
use $interval.this code will help you:
var callefunc=function() {
console.log('hey i am calle');
}
$scope.caller=function(){
var stop = $interval(callefunc, 1000);
}
here you can call a caller function when you want to start function callefunc on interval of 1 second .

Javascript setTimeout with 0 delay issue

I noticed a strange behavior: if I have a series of tasks and wish to defer their execution, then I can use a setTimeout with 0 delay for each of them.
(see http://javascript.info/tutorial/events-and-timing-depth#the-settimeout-func-0-trick)
Everything works perfectly: the tasks are queued and executed as soon as possible.
But ... if the invocation of the various setTimeout is very close, then I found that sometimes (rarely happens!) is not executed in the correct order.
Why?
Nobody ever promised they would be fired in the "correct" order (the tasks with the same timeout will be executed in the order they are set to time out). setTimeout only guarantees that:
each timeout is executed exactly once (unless the page dies in the meantime)
each timeout is executed no sooner than when it is supposed to.
There is no word about execution order. In fact, even if the implementor tried to preserve order (even as a side-effect), most likely there is not enough time resolution to provide a unique sort order to all tasks, and a binary heap (which may well be used here) does not preserve insertion order of equal keys).
If you want to preserve the order of your deferred tasks, you should only enqueue one when the previous one is done.
This should work:
var defer = (function(){
//wrapped in IIFE to provide a scope for deferreds and wrap
var running = false;
var deferreds = [];
function wrap(func){
return function(){
func();
var next = deferreds.shift();
if(next){
setTimeout(wrap(next),0);
}else{
running = false;
}
}
}
return function(func){
if(running){
deferreds.push(func);
}else{
setTimeout(wrap(func),0);
running = true;
}
}
})()
Demo: http://jsfiddle.net/x2QuB/1/
You can consider using jquery deferreds ( or some other implementation of deferreds), which can handle this pattern very elegantly.
The important point to note is that the deferred done callbacks are executed in the order in which they are added.
var createCountFn = function(val){
return function(){
alert(val)
};
}
// tasks
var f1 = createCountFn(1),
f2 = createCountFn('2nd'),
f3 = createCountFn(3);
var dfd = $.Deferred();
dfd.done(f1).done(f2).done(f3);
dfd.resolve();
demo
The HTML5 draft specification states that the setTimeout method can be run asynchronously (implying that the order that the callbacks will be executed may not be preserved), which could be what your browser is doing.
The setTimeout() method must run the following steps:
...
6. Return handle, and then continue running this algorithm asynchronously.
7. If the method context is a Window object, wait until the Document associated with the method context has been fully active for a further timeout milliseconds (not necessarily consecutively).
In any case one could workaround this issue by doing something similar to this:
function inOrderTimeout(/* func1[, func2, func3, ...funcN], timeout */)
{ var timer; // for timeout later
var args = arguments; // allow parent function arguments to be accessed by nested functions
var numToRun = args.length - 1; // number of functions passed
if (numToRun < 1) return; // damm, nothing to run
var currentFunc = 0; // index counter
var timeout = args[numToRun]; // timeout should be straight after the last function argument
(function caller(func, timeout) // name so that recursion is possible
{ if (currentFunc > numToRun - 1)
{ // last one, let's finish off
clearTimeout(timer);
return;
}
timer = setTimeout(function ()
{ func(); // calls the current function
++currentFunc; // sets the next function to be called
caller(args[currentFunc], timeout);
}, Math.floor(timeout));
}(args[currentFunc], timeout)); // pass in the timeout and the first function to run
}

How should I call 3 functions in order to execute them one after the other?

If I need call this functions one after other,
$('#art1').animate({'width':'1000px'},1000);
$('#art2').animate({'width':'1000px'},1000);
$('#art3').animate({'width':'1000px'},1000);
I know in jQuery I could do something like:
$('#art1').animate({'width':'1000px'},1000,'linear',function(){
$('#art2').animate({'width':'1000px'},1000,'linear',function(){
$('#art3').animate({'width':'1000px'},1000);
});
});
But, let's assume that I'm not using jQuery and I want to call:
some_3secs_function(some_value);
some_5secs_function(some_value);
some_8secs_function(some_value);
How I should call this functions in order to execute some_3secs_function, and AFTER that call ends, then execute some_5secs_function and AFTER that call ends, then call some_8secs_function?
UPDATE:
This still not working:
(function(callback){
$('#art1').animate({'width':'1000px'},1000);
callback();
})((function(callback2){
$('#art2').animate({'width':'1000px'},1000);
callback2();
})(function(){
$('#art3').animate({'width':'1000px'},1000);
}));
Three animations start at same time
Where is my mistake?
In Javascript, there are synchronous and asynchronous functions.
Synchronous Functions
Most functions in Javascript are synchronous. If you were to call several synchronous functions in a row
doSomething();
doSomethingElse();
doSomethingUsefulThisTime();
they will execute in order. doSomethingElse will not start until doSomething has completed. doSomethingUsefulThisTime, in turn, will not start until doSomethingElse has completed.
Asynchronous Functions
Asynchronous function, however, will not wait for each other. Let us look at the same code sample we had above, this time assuming that the functions are asynchronous
doSomething();
doSomethingElse();
doSomethingUsefulThisTime();
The functions will be initialized in order, but they will all execute roughly at the same time. You can't consistently predict which one will finish first: the one that happens to take the shortest amount of time to execute will finish first.
But sometimes, you want functions that are asynchronous to execute in order, and sometimes you want functions that are synchronous to execute asynchronously. Fortunately, this is possible with callbacks and timeouts, respectively.
Callbacks
Let's assume that we have three asynchronous functions that we want to execute in order, some_3secs_function, some_5secs_function, and some_8secs_function.
Since functions can be passed as arguments in Javascript, you can pass a function as a callback to execute after the function has completed.
If we create the functions like this
function some_3secs_function(value, callback){
//do stuff
callback();
}
then you can call then in order, like this:
some_3secs_function(some_value, function() {
some_5secs_function(other_value, function() {
some_8secs_function(third_value, function() {
//All three functions have completed, in order.
});
});
});
Timeouts
In Javascript, you can tell a function to execute after a certain timeout (in milliseconds). This can, in effect, make synchronous functions behave asynchronously.
If we have three synchronous functions, we can execute them asynchronously using the setTimeout function.
setTimeout(doSomething, 10);
setTimeout(doSomethingElse, 10);
setTimeout(doSomethingUsefulThisTime, 10);
This is, however, a bit ugly and violates the DRY principle[wikipedia]. We could clean this up a bit by creating a function that accepts an array of functions and a timeout.
function executeAsynchronously(functions, timeout) {
for(var i = 0; i < functions.length; i++) {
setTimeout(functions[i], timeout);
}
}
This can be called like so:
executeAsynchronously(
[doSomething, doSomethingElse, doSomethingUsefulThisTime], 10);
In summary, if you have asynchronous functions that you want to execute syncronously, use callbacks, and if you have synchronous functions that you want to execute asynchronously, use timeouts.
This answer uses promises, a JavaScript feature of the ECMAScript 6 standard. If your target platform does not support promises, polyfill it with PromiseJs.
Look at my answer here Wait till a Function with animations is finished until running another Function if you want to use jQuery animations.
Here is what your code would look like with ES6 Promises and jQuery animations.
Promise.resolve($('#art1').animate({ 'width': '1000px' }, 1000).promise()).then(function(){
return Promise.resolve($('#art2').animate({ 'width': '1000px' }, 1000).promise());
}).then(function(){
return Promise.resolve($('#art3').animate({ 'width': '1000px' }, 1000).promise());
});
Normal methods can also be wrapped in Promises.
new Promise(function(fulfill, reject){
//do something for 5 seconds
fulfill(result);
}).then(function(result){
return new Promise(function(fulfill, reject){
//do something for 5 seconds
fulfill(result);
});
}).then(function(result){
return new Promise(function(fulfill, reject){
//do something for 8 seconds
fulfill(result);
});
}).then(function(result){
//do something with the result
});
The then method is executed as soon as the Promise finished. Normally, the return value of the function passed to then is passed to the next one as result.
But if a Promise is returned, the next then function waits until the Promise finished executing and receives the results of it (the value that is passed to fulfill).
It sounds like you're not fully appreciating the difference between synchronous and asynchronous function execution.
The code you provided in your update immediately executes each of your callback functions, which in turn immediately start an animation. The animations, however, execute asyncronously. It works like this:
Perform a step in the animation
Call setTimeout with a function containing the next animation step and a delay
Some time passes
The callback given to setTimeout executes
Go back to step 1
This continues until the last step in the animation completes. In the meantime, your synchronous functions have long ago completed. In other words, your call to the animate function doesn't really take 3 seconds. The effect is simulated with delays and callbacks.
What you need is a queue. Internally, jQuery queues the animations, only executing your callback once its corresponding animation completes. If your callback then starts another animation, the effect is that they are executed in sequence.
In the simplest case this is equivalent to the following:
window.setTimeout(function() {
alert("!");
// set another timeout once the first completes
window.setTimeout(function() {
alert("!!");
}, 1000);
}, 3000); // longer, but first
Here's a general asynchronous looping function. It will call the given functions in order, waiting for the specified number of seconds between each.
function loop() {
var args = arguments;
if (args.length <= 0)
return;
(function chain(i) {
if (i >= args.length || typeof args[i] !== 'function')
return;
window.setTimeout(function() {
args[i]();
chain(i + 1);
}, 2000);
})(0);
}
Usage:
loop(
function() { alert("sam"); },
function() { alert("sue"); });
You could obviously modify this to take configurable wait times or to immediately execute the first function or to stop executing when a function in the chain returns false or to apply the functions in a specified context or whatever else you might need.
I believe the async library will provide you a very elegant way to do this. While promises and callbacks can get a little hard to juggle with, async can give neat patterns to streamline your thought process. To run functions in serial, you would need to put them in an async waterfall. In async lingo, every function is called a task that takes some arguments and a callback; which is the next function in the sequence. The basic structure would look something like:
async.waterfall([
// A list of functions
function(callback){
// Function no. 1 in sequence
callback(null, arg);
},
function(arg, callback){
// Function no. 2 in sequence
callback(null);
}
],
function(err, results){
// Optional final callback will get results for all prior functions
});
I've just tried to briefly explain the structure here. Read through the waterfall guide for more information, it's pretty well written.
your functions should take a callback function, that gets called when it finishes.
function fone(callback){
...do something...
callback.apply(this,[]);
}
function ftwo(callback){
...do something...
callback.apply(this,[]);
}
then usage would be like:
fone(function(){
ftwo(function(){
..ftwo done...
})
});
Since you tagged it with javascript, I would go with a timer control since your function names are 3, 5, and 8 seconds. So start your timer, 3 seconds in, call the first, 5 seconds in call the second, 8 seconds in call the third, then when it's done, stop the timer.
Normally in Javascript what you have is correct for the functions are running one after another, but since it looks like you're trying to do timed animation, a timer would be your best bet.
asec=1000;
setTimeout('some_3secs_function("somevalue")',asec*3);
setTimeout('some_5secs_function("somevalue")',asec*5);
setTimeout('some_8secs_function("somevalue")',asec*8);
I won't go into a deep discussion of setTimeout here, but:
in this case I've added the code to execute as a string. this is the simplest way to pass a var into your setTimeout-ed function, but purists will complain.
you can also pass a function name without quotes, but no variable can be passed.
your code does not wait for setTimeout to trigger.
This one can be hard to get your head around at first: because of the previous point, if you pass a variable from your calling function, that variable will not exist anymore by the time the timeout triggers - the calling function will have executed and it's vars gone.
I have been known to use anonymous functions to get around all this, but there could well be a better way,
You could also use promises in this way:
some_3secs_function(this.some_value).then(function(){
some_5secs_function(this.some_other_value).then(function(){
some_8secs_function(this.some_other_other_value);
});
});
You would have to make some_value global in order to access it from inside the .then
Alternatively, from the outer function you could return the value the inner function would use, like so:
one(some_value).then(function(return_of_one){
two(return_of_one).then(function(return_of_two){
three(return_of_two);
});
});
ES6 Update
Since async/await is widely available now, this is the way to accomplish the same:
async function run(){
await $('#art1').animate({'width':'1000px'},1000,'linear').promise()
await $('#art2').animate({'width':'1000px'},1000,'linear').promise()
await $('#art3').animate({'width':'1000px'},1000,'linear').promise()
}
Which is basically "promisifying" your functions (if they're not already asynchronous), and then awaiting them
//sample01
(function(_){_[0]()})([
function(){$('#art1').animate({'width':'10px'},100,this[1].bind(this))},
function(){$('#art2').animate({'width':'10px'},100,this[2].bind(this))},
function(){$('#art3').animate({'width':'10px'},100)},
])
//sample02
(function(_){_.next=function(){_[++_.i].apply(_,arguments)},_[_.i=0]()})([
function(){$('#art1').animate({'width':'10px'},100,this.next)},
function(){$('#art2').animate({'width':'10px'},100,this.next)},
function(){$('#art3').animate({'width':'10px'},100)},
]);
//sample03
(function(_){_.next=function(){return _[++_.i].bind(_)},_[_.i=0]()})([
function(){$('#art1').animate({'width':'10px'},100,this.next())},
function(){$('#art2').animate({'width':'10px'},100,this.next())},
function(){$('#art3').animate({'width':'10px'},100)},
]);
I use a 'waitUntil' function based on javascript's setTimeout
/*
funcCond : function to call to check whether a condition is true
readyAction : function to call when the condition was true
checkInterval : interval to poll <optional>
timeout : timeout until the setTimeout should stop polling (not 100% accurate. It was accurate enough for my code, but if you need exact milliseconds, please refrain from using Date <optional>
timeoutfunc : function to call on timeout <optional>
*/
function waitUntil(funcCond, readyAction, checkInterval, timeout, timeoutfunc) {
if (checkInterval == null) {
checkInterval = 100; // checkinterval of 100ms by default
}
var start = +new Date(); // use the + to convert it to a number immediatly
if (timeout == null) {
timeout = Number.POSITIVE_INFINITY; // no timeout by default
}
var checkFunc = function() {
var end = +new Date(); // rough timeout estimations by default
if (end-start > timeout) {
if (timeoutfunc){ // if timeout function was defined
timeoutfunc(); // call timeout function
}
} else {
if(funcCond()) { // if condition was met
readyAction(); // perform ready action function
} else {
setTimeout(checkFunc, checkInterval); // else re-iterate
}
}
};
checkFunc(); // start check function initially
};
This would work perfectly if your functions set a certain condition to true, which you would be able to poll. Plus it comes with timeouts, which offers you alternatives in case your function failed to do something (even within time-range. Think about user feedback!)
eg
doSomething();
waitUntil(function() { return doSomething_value===1;}, doSomethingElse);
waitUntil(function() { return doSomethingElse_value===1;}, doSomethingUseful);
Notes
Date causes rough timeout estimates. For greater precision, switch to functions such as console.time(). Do take note that Date offers greater cross-browser and legacy support. If you don't need exact millisecond measurements; don't bother, or, alternatively, wrap it, and offer console.time() when the browser supports it
If method 1 has to be executed after method 2, 3, 4. The following code snippet can be the solution for this using Deferred object in JavaScript.
function method1(){
var dfd = new $.Deferred();
setTimeout(function(){
console.log("Inside Method - 1");
method2(dfd);
}, 5000);
return dfd.promise();
}
function method2(dfd){
setTimeout(function(){
console.log("Inside Method - 2");
method3(dfd);
}, 3000);
}
function method3(dfd){
setTimeout(function(){
console.log("Inside Method - 3");
dfd.resolve();
}, 3000);
}
function method4(){
console.log("Inside Method - 4");
}
var call = method1();
$.when(call).then(function(cb){
method4();
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

Categories