wait for function done (with setInterval) and run next function - javascript

how to run next function after first done with setInterval?
for example:
step1();
step2();
setInterval(step1, 1000).done(function() {
setInterval(step2, 1000).done( /* next step */);
});
please help me with solution!

Edit: This is an old answer. Now you can achieve this using promises also but the code will be slightly different.
If you don't want to use a promise you can use a simple flag to achieve such a thing. Please see example below:
var flag = true;
function step1() {
console.log('title');
}
function step2() {
console.log('subtitle');
}
function wrapper() {
if(flag) {
step1();
} else {
step2();
}
flag = !flag;
}
setInterval(wrapper, 30000);

If you want to chain functions on completion you can use callback functions.
Example:
function first(callback) {
console.log('Running first');
if (callback) {
callback();
}
}
function second() {
console.log('Running second function');
}
first(second);
The first function checks if a callback is used and then runs it. If there is no callback function nothing happens. You can chain functions this way.
You can also use anonymous functions.
first(function () {
console.log('This function that will run after the first one);
});
If you use setTimeout() you can't be sure whether the previous function has completed. A better way would be to use promises.
Understanding Promises
I hope I understood your question right. Good luck!

First of all setInterval can not be done by itself, it will fire infinitely if you not clear it with clearInterval.
But if you have some async action inside your function and whant to wait for it and then call another function you may just promisify it like Avraam Mavridis suggested.
function step1() {
var deferred = $.Deferred();
setTimeout(function () {
alert('I am step 1');
deferred.resolve();
}, 1000);
return deferred.promise();
}
function step2() {
alert('I am step 2');
}
step1().done(step2);
JsFiddle

Related

javascript callback pattern using simple example

I've been unable to find a simple example of a javascript callback pattern for my purpose and an answer to the following question would be very helpful.
Supposing I've 2 functions which each display an alert:
function hello1() {
setTimeout(function(){
alert("hello1");
}, 500);
}
function hello2() {
alert("hello2");
}
if I'm using this function,
function saythehellos()
{
hello1();
hello2();
}
the alert "hello2" will display first followed by the alert "hello1"
How can I change the function saythehellos() using a callback pattern so that the alert "hello1" is displayed first followed by the alert "hello2"?
As per quetion, you can define a callback pattern as per the following, define callback function as an argument.
function hello1(callback) {
setTimeout(function(){
alert("hello1");
callback();
}, 500);
}
function hello2() {
alert("hello2");
}
hello1(hello2);
In ES6 a special syntax to work with promises in a more comfortable fashion, called async/await. It’s surprisingly easy to understand and use. you can also use it. In behind the scene, async/await work as callback
Edited as per request:
You can do it by the third function(saythehellos) as per the following chain.
function hello1(callback) {
setTimeout(function(){
alert("hello1");
callback();
}, 500);
}
function hello2(callback) {
alert("hello2");
callback();
}
function saythehellos(callback) {
hello1(function() {
hello2(function() {
callback();
});
});
}
saythehellos(function(){alert('all done')});
You could use ES7's async/await syntax with a promise. In your hello1() method you can return a promise which will alert() and then resolve to indicate that your hello1 method is complete. Then saythehellos() will wait for hello1() to resolve (as we are using the await keyword) and then it will continue to execute hello2():
function hello1() {
return new Promise(function(resolve, reject) {
setTimeout(function() {
alert("hello1");
resolve();
}, 500);
});
}
function hello2() {
alert("hello2");
}
async function saythehellos() { // make async as we want to use await within this method
await hello1();
hello2();
}
saythehellos();
Alternatively, if you're looking for something a little more browser compatible, you can use the .then callback on the returned promise from hello1() (which is essentially what async/await is doing under the hood). The .then callback will be fired when the returned promise has resolved:
function hello1() {
return new Promise(function(resolve, reject) {
setTimeout(function() {
alert("hello1");
resolve();
}, 500);
});
}
function hello2() {
alert("hello2");
}
function saythehellos() {
hello1().then(function(result) {
hello2();
});
}
saythehellos();
The simple callback way is:
function hello1(hello2Callback) {
alert("hello1");
hello2Callback && hello2Callback();
}
hello1(function() {
alert("hello2");
});
I hope this will help you. The callback function is a function that is passed as an argument. So, when calling hello1(), I am passing a complete function definition. This argument is called callback function.
The Promise is a new efficient and clean way on handling callbacks. You can check Javascript Promise over Google.
Simple approach to achieve this:
function Hello1(){
setTimeOut(onTimeOutRaise,500)
}
function onTimeOutRaise(){
alert("Hello1");
Hello2();
}
function Hello2(){
alert("Hello2")
}
Here "onTimeOutRaise" itself a callback.

Understanding callbacks in NodeJS

function firstFunction(_callback){
// do some asynchronous work
// and when the asynchronous stuff is complete
_callback();
}
function secondFunction(){
// call first function and pass in a callback function which
// first function runs when it has completed
firstFunction(function() {
console.log('huzzah, I\'m done!');
});
}
This is an example from this site, I would like help understanding it.
If I have a function that sums 2 number and the other returns it. So:
var z = 0;
function firstf (x, y, callback){
z = x + y;
callback();
}
function secondf () {
console.log(z);
}
I dont get how this works? How do I make it so that secondf waits until firstf is done using callbacks?
After define 2 function, you call:
firstf(2,3,secondf);
Follow : z=2+3 then call function callback. And now, function callback ~ secondf :
z=2+3 ;
secondf();
If you want to the second block to wait until the first block is done. Then using callback makes no sense.
Because the main concept of callback is to provide an asynchronous platform.
A callback is a function call at the completion of a given task, hence prevents any blocking which may might occur if the first block takes long time to load data.
So, if you want both the blocks to work asynchronously the use callback, and to achieve what you are asking simply call the second function after the task of block one is done.
For better understanding go through this link,
https://docs.nodejitsu.com/articles/getting-started/control-flow/what-are-callbacks/
Best of luck!
You can use "promise" concept to ensure that the secondf waits until firstf is done:
function firstf(x,y){
return new Promise(
function (resolve, reject) {
resolve(x+y);
});
}
function secondf(){
firstf(x,y).then ( function (result){
console.log(result);
});
}
By re-ordering your code:
edit Made code async for demo purposes
var z = 0;
function firstf(x, y, callback) {
console.log("Inside firstf");
z = x + y;
console.log("Will call callback in 1 second");
// Lets make this function async.
setTimeout(function() {
console.log("Calling callback");
callback();
}, 1000);
}
function secondf() {
console.log("Inside secondf");
console.log(z);
console.log("Leaving secondf");
}
firstf(1, 2, secondf);

Delay Between Functions

this is my code snippet.
function customFadeIn () {
$("img.imgKit").each(function(index) {
$(this).delay(1000*index).fadeIn("slow");
});
console.log("one runs");
}
function customFadeOut () {
$("img.imgKit").each(function(index) {
$(this).delay(1000*index).not(document.getElementById('card-6')).fadeOut("slow" , function () {
$("#card-6").delay(1000).rotate({angle:0});
});
});
console.log("two runs");
}
I want the customFadeOut runs only after customFadeIn is done, therefore I call it by this
customFadeIn();
customFadeOut();
But it did not work, I think I did something wrong here, a help would be really helpful.
You can make usage of jQuerys Deferred / promise objects. Animations do also "inherit" those objects and you can apply jQuery.when() to shoot for multiple promises to finish.
There are several ways to re-structure your code for that, a simple implementation of this could look like:
(function() {
var promises = [ ];
function customFadeIn () {
$("img.imgKit").each(function(index) {
promises.push( $(this).delay(1000*index).fadeIn("slow").promise() );
});
}
function customFadeOut () {
jQuery.when.apply( null, promises ).done(function() {
$("img.imgKit").each(function(index) {
$(this).delay(1000*index).not(document.getElementById('card-6')).fadeOut("slow" , function () {
$("#card-6").delay(1000).rotate({angle:0});
});
});
console.log("two runs");
});
}
}());
If I did everything correct there, customFadeOut sets up a listener which waits for all animations / promises to finish, before it runs its own code. You don't even have to explicitly call the .promise() method at the end, jQuery applies some white magic to link that node with a promise internally for you.
Demo: http://jsfiddle.net/RGgr3/
Looks like I did everything correct ;)

how to avoid callback chains?

I need a bunch of functions to be called in strict order. It's also very important that the next function waits until the previous one has finished.
Right now I'm using chained callbacks:
callMe1(function(){
callMe2(function(){
callMe3(function(){
callMeFinal();
});
});
});
This works but seems to be a little ugly.
Any suggestions for a different approach?
If you use jQuery, then you can use queue to chain the functions.
$(document)
.queue(callMe1)
.queue(callMe2);
where callMeX should be of form:
function callMeX(next) {
// do stuff
next();
}
You can implement a "stack" system:
var calls = [];
function executeNext(next) {
if(calls.length == 0) return;
var fnc = calls.pop();
fnc();
if(next) {
executeNext(true);
}
}
/*To call method chain synchronously*/
calls.push(callMe3);
calls.push(callMe2);
calls.push(callMe1);
executeNext(true);
/*To call method chain asynchronously*/
calls.push(callMe3);
calls.push(function(){
callMe2();
executeNext(false);
});
calls.push(function(){
callMe1();
executeNext(false);
});
Not sure if this would help you, but there is a great article on using deferreds in jQuery 1.5. It might clean up your chain a bit...
Also, my answer on Can somebody explain jQuery queue to me has some examples of using a queue for ensuring sequential calls.
You might want to pass parameters to the functions, I do not believe you can at the time of this writing. However...
function callMe1(next) {
console.log(this.x);
console.log("arguments=");
console.log(arguments);
console.log("/funct 1");
this.x++;
next();
}
function callMe2(next) {
console.log(this.x);
console.log("arguments=");
console.log(arguments);
console.log("/funct 2");
this.x++;
next();
}
function callMe3(next) {
console.log(this.x);
console.log("arguments=");
console.log(arguments);
console.log("/funct 3");
this.x++;
next();
}
var someObject = ({x:1});
$(someObject).queue(callMe1).queue(callMe2).queue(callMe3);
Wrapping your functions, arguments intact, with an anonymous function that plays along with .queue works too.
Passing Arguments in Jquery.Queue()
var logger = function(str, callback){
console.log(str);
//anything can go in here, but here's a timer to demonstrate async
window.setTimeout(callback,1000)
}
$(document)
.queue(function(next){logger("Hi",next);})
.queue(function(next){logger("there,",next);})
.queue(function(next){logger("home",next);})
.queue(function(next){logger("planet!",next);});
Example on JSFiddle: http://jsfiddle.net/rS4y4/

jQuery pause function execution and do something else while paused

I have something like this:
function doSomething() {
var obj = $('somediv');
...
waitAndDoSomethingElse(obj);
...
$('somediv').show();
...
}
function waitAndDoSomethingElse(obj) {
obj.fadeIn();
....
}
I want doSomething() to pause... execute waitAndDoSomethingElse() and then continue...
Any ideas?
Thank you
EDIT:
I'll try to explain better, sorry if my question was confused...
function showSomething() {
var whatToShow = $('#div');
doSomethingElse();
whatToShow.fadeIn('slow');
}
function doSomethingElse() {
$('#someDiv').appendTo($('#someOtherDiv'));
$('#somethingElse').fadeIn('slow');
...
}
In this example whatToShow.fadeIn will fire without waiting for doSomethingElse to end...
Use the animation callbacks. All the animations have them as the last arg.
See here for the fadeIn docs.
$('#someElement').fadeIn('slow', callbackFn);
function callbackFn(){
//executed after the fadeIn is complete
}
If you are not using the animation helpers then you can use the same methodology and pass callback functions to other functions which can choose when to call the callback.
var callbackFn = function(){ //do something };
doSomething( callbackFn )
function doSomething( callback ){
doOtherStuff();
//call the callback
callback && callback()
}
Another option is to use window.setTimeout to fire a function after x milliseconds.
Do this
function doSomething() {
var obj = $('somediv');
...
waitAndDoSomethingElse(obj);
}
function waitAndDoSomethingElse(obj) {
obj.fadeIn();
// if you want a pause here you can also add the next call in a setTimeout()
$('somediv').show(); // this call is executed only after
}

Categories

Resources