Measuring time of execution on method - javascript

Let's say we have this:
function myMethod1() {
...
}
and later in the code:
myMethod1();
alert('myMethod1() was executed!');
I need to set timeout for the alert so that it will be called after myMethod1() executes. But how do I know the value of the second parameter for the setTimeout function? How do I measure the time needed for myMethod1() to execute?
MyMethod1() has an async ajax call.

If your method performs an asynchronous task, it's common to pass a callback function like so:
function myMethod(cb)
{
// some code, such as $.ajax
$.ajax({
url: 'example.com',
complete: function() {
// we're done, notify callback
cb();
}
});
}
Then, cb is passed in like this upon execution:
myMethod(function() {
alert('method is done');
});
alert('method returned, but is still doing stuff in the background');
This is the mantra of asynchronous design; every method that performs a task in the background will have some way of notifying a callback function of its completion.
If the method is synchronous however, you could call cb() at the end of the function body, but it would be much easier to keep what you had:
myMethod();
alert('method is done');

You dont need to. The way that you have set it up, the alert will always fire after myMethod1() finishes.

you can use a time stamp, will be precise to the millisecond.
You'll need 2 vars, one to hold the start time and one for the end tume.
And to set those var, where you want to calculate. So
///EDITED version below to make it global..
put this at he top of you js code:
var ts_start;
var ts_stop;
put this where you want to START calculating the time:
ts_start =new Date().getTime();
put this where you want to STOP calculating the time:
ts_stop =new Date().getTime();
and you can alert the millesecond by making the diff bewteen them.
alert(ts_stop-ts_start);
OR shove it in a variable...

Related

javascript callback function after several jQuery calls

I got the following code:
$('#some_object_id').hide();
$('div#some_version_div').hide();
$('#some_another_object_id').show();
someFunction();
I want to issue my someFunction() only after the last of these 3 finishes its action. The problem is that from time to time they finish in different order (ie now the last may be the second, the other time the first one etc.) Now someFunction() fires without waiting for these 3 to finish. Any ideas how to fix it? Thank you.
jQuery's hide() and show() functions accept a function as their argument which is called when they finish. (aka, a callback).
$('selector').hide(function onFinish() {
console.log('done')
})
To combine three of them together, I'd convert them to a Promise, like so:
function promisify(func,selector){
return new Promise(function (resolve) {
$(selector)[func](resolve)
})
}
Promise.all([
promisify('hide', '#test'),
promisify('hide', '#test1'),
promisify('show', '#test2')
]).then(function onFinish() {
console.log('done!')
})
You can pass a callback function to hide, and show that gets executed when the animation is complete. So if you want them to execute in order just call each one in the callback of the previous one.
$('#some_object_id,div#some_version_div').hide(()=>{
$('#some_another_object_id').show(()=>{
someFunction();
});
});
And if you want to prevent a bunch of inner callbacks, and not require each animation run dependent of the others, you could use a flag. Increment the flag in each callback, check to see if its at a certain value, and then execute your function if it is.
var flag = 0;
function incrementFlag(){
flag++;
if(flag>=2){
flag=0;
someFunction();
}
}
$('#some_object_id,div#some_version_div').hide(incrementFlag);
$('#some_another_object_id').show(incrementFlag);
You could also modify the above to use a Promise, but will leave that for you to try.
You should use a variable that you initially set to 0 and increase on every complete call. As soon as the variable hit the value 3 and can call your function:
var completed = 0;
elem.hide(400, function(){
completed++;
if(completed > 2) someFunction();
});
//same for other elements...

Want to set delay in javascript

I want to set delay in javascript code so that XML file generated before running of javascript . Here is my html code
<body onLoad="Func1Delay()">
<div id="map"></div>
</body>
In this Func1Delay() function i have written code to delay execution of javascript
function Func1Delay()
{
setTimeout("load()", 3000);
}
load() is javascript function ? how can i delay execution of javascript code so that xml file successfully generated before code execution??
Seems like your downloadUrl function provides a callback. The callback function fires automatically, after the XML is loaded. You do not need a 3 second delay, just move your logic inside the callback function. Something like this:
function Func1Delay() {
downloadUrl("location.xml", function (data) {
var xml = data.responseXML;
// do any thing with xml, it is loaded!
// alert(xml);
});
}
That's how you do it, except you don't want to use a string (although it works — provided you have a function called load defined at global scope). setTimeout schedules a function to be called a given number of milliseconds later.
It's better to give it an actual function reference:
function Func1Delay() {
setTimeout(load, 3000);
function load() {
// Stuff to do three seconds later
}
}
Note that the event you're using to trigger it, the onload of body, already happens really, really late in the page load cycle, and so whatever you're waiting for may already be done; conversely, if it might take more than three seconds, you might not be waiting long enough. So if there's something you can check to see whether it's done or not, you can poll, like this:
function Func1Delay() {
check();
function check() {
if (theWorkIsDone) {
// Do something with the work
}
else {
// Check back in 100ms (1/10th of a second)
setTimeout(check, 100);
}
}
}
You want the function to execute as soon as possible, but in every case after your xml has been successfully generated.
In this case you should prevent using a fixed amount of time (because you don't know the value exactly), but try the following:
function load(){
if (/*check here if the xml has *not yet* been generated*/){
setTimeout(load,50); // try again in 50 milliseconds
return;
}
// do your stuff here
}
This loops as long as your xml is not ready, and kicks in as soon as it's available.
General about setTimeout:
You can pass a string, but this is highly discouraged from for several reasons.
Instead pass a function reference or a function like this:
// function reference
setTimeout(load,3000) // no `()` !
// function
setTimeout( function(){load()},3000)
If you need paramters be passed to the function, you can't use the first option but need to use the second one, where you can easily pass them load(params).
If you pass a function like this: setTimeout(load(),3000) it executes the function load and passes its return value to the timeout. You however want the function invoked after 3 seconds and thus only pass the reference to the function.
Notice however, that you have a different scope if you execute the functions this way.

How to create a pause in javascript/jquery code that follows a call to asynchronous function

How can I call an asynchronous function and then create a pause in the code that follows the call to the function so that I may be (almost) sure that the asynchronos function has finished?
I don't want to put the code that follows the call inside a function and then delay it to achieve this, just pause the code as it is for a few seconds.
Here is what I mean:
<script>
asynchronousFunction(); // start running immediatly
waitFor10Seconds(); // only the following code should wait while the async
// function is running in the background
rest of the code; // this code will start running after 10 seconds have passed
// since the async function has been called
</script>
It's called setTimeout
asyncThing();
setTimeout(function() {
// do stuff
}, 10000);
Ideally though the async operation should allow you to pass a callback so you turn it into
asyncThing(function() {
// do stuff
});
As mentioned, you should really use a callback. It's easy with jQuery:
$.get("page.php", "key1=value1", function(data) {
// Code in here will be executed when response has been received
});
http://api.jquery.com/jQuery.get/
You can of course use $.post() if you'd rather POST the data.
Aldo a callback is better practice, this what you asked for
window.setTimeout(function(){ ... }, 10000);

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>

Javascript and timing, specifically with callbacks

I want to make sure I understand callbacks properly, and javascript timing etc. in general.
Say my code looks like this, is it guaranteed to execute in order?
SetList(); // initializes the var _list
Some.Code(_list, function(data) {
// update list
});
DoSomething(_list); // operates on _list
Update
What I am seeing is SetList calls, then DoSomething, then Some.Code.
Some.Code calls another function. so:
Some.Code(_list, function() {
//load _list from ajax request
Other.Code.WithCallback(_list, function(){....});
});
I guess to fix this, I have to add DoSomething to the inner function as another callback?
SetList(), Some.Code() and DoSomething() will execute in that order, one after the other. The anonymous function passed as the second argument to Some.Code() could be called during the execution of Some.Code() (before the function returns and DoSomething() is called) or it could be called at a later time by another function, and event handler or timer, it all depends on when you specified it to be called.
Since you're using ajax, the request to the remote server is made on a separate thread, so the executing javascript thread continues to run and call other functions until a response (or, more specifically, for the onreadystatechange event to fire). When the ready state of the ajax request changes, its readystatechange event handler is queued to be called -- meaning it will execute as soon as all currently executing scripts finish.
If you want DoSomething() to execute after the response is received via ajax, you should run it to the end of your callback function instead.
That code would execute in order:
SetList(), then Some.Code(), then function(data), then DoSomething().
JavaScript is single-threaded, and executes in order. The only way that things would happen out of sync is if you set an interval/timer within Some.Code() or function(data) that called another function.
If you had:
var i=0;
functionCall() //some long process that sets i=1;
if (i==1) { alert("In Order!"); } else { alert("Out of Order!"); }
That would alert "In Order," But if you had:
var i=0;
setTimeout(functionCall, 1000) //some long process that sets i=1;
if (i==1) { alert("In Order!"); } else { alert("Out of Order!"); }
That would execute "Out of Order," because the third line would execute before functionCall() is called.
Updated Answer
Because you are using Ajax, I'm guessing you are making an asynchronous call, which is the reason for the delay. You have a callback function, but it's still waiting to be called back, so Javascript moves on to execute the next line while it waits.
To execute in the order you want, you'll need to do this:
SetList(); // initilizes the var _list
Some.Code(_list, function(data) {
// update list
DoSomething(_list); // operates on _list
});
This way, you can ensure that DoSomething() is called when your callback method is called, and not before.

Categories