My code is something like this:-
function doStuff(){
// Note:- this funcion take 50ms for ececution as i have put
// timeout
setTimeout(function(){
// some line of code
....
}, 50);
return;
}
doStuff();
console.log('This should execute after doStuff() complete its work.")
// after that more many lines of code and more stuff are here
.....
.....
Now what I want is, as you can see here that doStuff() takes 50ms of time to execute so the code which is after doStuff() it should execute after doStuff() complete it's work. For example, that console should print after doStuff() is completed.
Note that I know I can put timeOut there, but I can't put timeout because of some limitations as I am working on an opensource project so I can't change code which is written after that function call, i can't even wait for promise as i told i can't change that code what I can do is change the doStuff method I have made that method. Is there any way to stop doStuff() return, like doStuff() should not return until that delay is over, one way is we can recursively call doStuff but I want the better way to do that. Please help me out.
You either need to use callbacks, or promises. Here's an example of promises:
function doStuff(){
var promise = new Promise((resolve) => {
// Note:- this funcion take 50ms for ececution as i have put
// timeout
setTimeout(function(){
// some line of code
resolve();
}, 1000);
});
return promise;
}
async function main() {
console.log('Start.');
await doStuff();
console.log('This should execute after doStuff() complete its work.');
}
main();
Alternatively, use .then() of promises, if you don't want to use the nice async/await functionality that ES6 brings:
function doStuff(){
var promise = new Promise((resolve) => {
// Note:- this funcion take 50ms for ececution as i have put
// timeout
setTimeout(function(){
// some line of code
resolve();
}, 1000);
});
return promise;
}
console.log('Start.');
doStuff().then(() => console.log('This should execute after doStuff() complete its work.'));
Here's an example of using callbacks:
function doStuff(callback){
setTimeout(function(){
// some line of code
callback();
}, 1000);
}
console.log('Start.');
doStuff(function() {
console.log('This should execute after doStuff() complete its work.');
});
Related
I have got more than 10 functions that are being called at the same time. I want to synchronize them. I want to do it without a timeout, meaning next function gets executed when the one before finishes. Is there a neat way to do it?
Just use await on everything, if it returns an actual value it will immediately resolved, otherwise it will wait to be resolved:
function fn1() {
return 10;
}
function fn2() {
return new Promise(r => setTimeout(r, 1000, 20));
}
function fn3() {
return 30;
}
and then:
async function main() {
console.log(await fn1()); // 10
console.log(await fn2()); // 20, after 1sec
console.log(await fn3()); // 30
}
main();
In that case you can also have an array of functions and loop through it, using always await and don't care about the function itself (if it's async or what).
P.S.
I just used the timeout for demo purpose, since I didn't have any real async code, I know you don't want to use it; it could be an http request for example (fetch), anything is async basically.
You need to provide your requrement. But you can use Async if that solves your problem
function f1(cb){
cb();
}
function f2(cb){
cb();
}
function f3(cb){
cb();
}
...etc
then...
f1(f2(f3(...etc)));
this is not the better way to go... but is good for learning what callback hell is
I have a super simple question. I have an onclick function that takes a good 10 seconds to complete. Therefore I want to add a 'Loading, please wait' text while the function completes.
If I do this:
javascript:
function onclickFunction(){
addPleaseWait();
runSlowFunction();
addFinishedText();
}
Then of course the end result is that the slow function runs first, then addPleaseWait and FinishedText run 2nd and 3rd. What is the proper way to do this?
If you are allowed to use ES6 function, I would suggest you use promise to run your function.
function onclickFunction() {
startLoader();
longFunction().then(function(data) => {
// long function is done, remove loader
return removeLoader();
})
}
function longFunction() {
return new Promise(function(resolve, reject) {
/*
* the parameter resolve tell when to finish. If you pass a function, it will finish once all the instruction of the function is done.
* the parameter reject is used to manage error.
*/
resolve(function() {
// Do you long function stuff
})
})
}
This method could seams a little bit complicated for what you are trying to achieve, but I think it is a great way to handle slow function. To make sure everythings comes in the right order.
If you wish to learn more about promise, look at this Mozilla docs link
function call() {
//your function here for example :
$("#yourFunction").html("yourFunction is executing....");
$("#test").html("Please Wait....."); // during your function
setTimeout(function() {
$("#yourFunction").html("yourFunction is completed....");
$("#test").html("done!!!!"); // after your function completed
}, 1000); // if you need more or less time change here
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
<button onclick=call()>Click</button>
<div id="yourFunction"></div>
<div id="test"></div>
You need a callback in your slow function, for example
runSlowFunction(callback) {
// ... do all slow things, and in the end, call your function
callback();
}
& then, your onclick function changes to
function onclickFunction(){
addPleaseWait();
runSlowFunction(addFinishedText);
// pass addFinishedText as the callback,
// which gets called after the slow function is done
}
So basically I have a function that has a setTimeout within it like so:
function foo(){
console.log('starting');
setTimeout(function(){
console.log('done');
}, 2000); // some arbitrary delay
}
and I want to call this function, have it truly complete, and then call a second function when it has ended:
foo();
secondFunction();
Is there a way that I can wait for foo() to finish running, including its setTimeout call, before secondFunction() fires? I suspect there is a way to do this with Promises because I've seen this problem solved with Promises before, however all the solutions I've seen includes tampering with the initial function that has the setTimeout; in my situation I cannot alter foo() at all.
Is there a way to solve this problem without altering foo() at all? This means I can't create Promises inside foo() nor can I add a callback function to foo() explicitly.
You can monkey-patch setTimeout because it's a property of the global object:
function trapTimeout() {
return new Promise(function(resolve, reject) {
var setTimeout = window.setTimeout;
window.setTimeout = function(cb, delay) {
var args = [].slice.call(arguments, 2);
setTimeout.call(window, function() {
window.setTimeout = setTimeout;
cb.apply(null, args);
resolve();
}, delay, ctx);
}
});
}
var trap = trapTimeout();
foo();
trap.then(function() { console.log('really done') });
This is a moderately nasty hack. It could well barf if something else creates a timer after this code (since the .then call doesn't stop any following code or the event loop from running, and the monkey patching remains in place until after the timeout is triggered).
I have a JavaScript function; from that am calling a delay function.
function(){
// code
doDelay();
// some other functionality....
}
function doDelay(){
setTimeout(function() {alert("after wait");}, 10000);
}
after waiting 10 seconds alert is coming after wait. but its not again continue the some other functionality.... of my main function.. After delay I want to execute the remaining functionality. How can I do that?
The setTimeout function does not delay execution. Instead, it schedules a function to be executed at a later time. To do what you want you need to change your code to this:
function(){
...
...
doDelay(function(){
some other functionality....
});
}
function doDelay(callback){
setTimeout(function() {callback()}, 10000);
}
Indeed, javascript already has a doDelay function. It's called setTimeout:
function(){
...
...
setTimeout(function(){
some other functionality....
},10000);
}
If you want the outer function to also delay execution of code that comes after it, you also need to pass a callback to it:
function foo (callback){
...
...
doDelay(function(){
some other functionality....
callback();
});
}
So that, for example, it allows you to rewrite something like this:
foo();
// do other stuff after foo...
to this:
foo(function(){
// do other stuff after foo...
});
You basically need to restructure your logic around callbacks.
Can't you wrap the other functionality in another function, then from your SetTimeout call that function?
function(){
doDelay();
}
function doDelay(){
setTimeout(function() {alert("after wait");andTheRest();}, 10000);
}
function andTheRest(){
//Rest of the stuff here
}
doDelayAndThenContinue(){
setTimeout(function() {alert("after wait");
//do other functionality here
}, 10000);
}
Remove the do other functionality from main method and put in setTimeout
I'm trying to make a removeClass function work right after another function ends, so I have this script to call a fittocontainer:
function fittocontainer(){
$('.fittocontainer').fittocontainer()
}
And I want that after the function 'fittocontainer' ends, apply this function:
setTimeout ( function(){
$('#footer').removeClass("active");
})
How can I integrate the setTimeout function with the 'fittocontainer()' to work after it has just ended?
Is fittocontainer a function that you made? If so, and it is asynchronous, you will have to add a callback like:
function fittocontainer (cb) {
//do some stuff
cb();
}
Then you can call it passing a function or even an anonymous function like:
fittocontainer(function () {
// do stuff afterwards
});
If this function is updating the DOM it is most likely asynchronous. Using a timeout to try and execute code after an async method is very dangerous and should never be done.
If it is synchronous, you can simply call a function on the next line and know that it will execute after fittocontainer is complete.
Also remember that you need a timeout on the setTimeout like:
setTimeout(function(){
$('#footer').removeClass("active");
}, 1000);
that is a timeout of 1 second
setTimeout() is about time (minutes, seconds), if you only want to execute that function at the end, you could just call it, or you could use a callback function:
function fittocontainer(callback){
$('.fittocontainer').fittocontainer();
callback();
}
and then call fittocontainer:
fittocontainer(function(){
$('#footer').removeClass("active");
});