I'd want to do, in my case, the call document.getElementById only after a previous function has completed, but it happens the opposite: it first (or at the same time) execute the document call, then the function.
In my specific case, I have a rocket and a counter: the rocket image has to change after the execution of the contatore() function.
Here is my function:
function rocketLaunch(){
contatore(10);
document.getElementById("imgRazzo").src = imgRazzoAcceso.src;
}
And here is contatore function, that uses setTimeout:
function contatore(number){
/* if 0, we have to stop the counter and return to the caller */
if(number == 0){
return;
}else{
/* js recursive: wait 1 second, than re-call this function with number-1 as parameter*/
setTimeout(function(){contatore(number - 1)}, 1000);
/* you can finally inner the html */
document.getElementById("main").innerHTML = number;
}
}
4 Answers 4
I bet you have some timeout/interval/ajax call in your function. That's why it's asynchronous. You need to declare callback, pass it as argument and call in contatore(); when it finished.
Example:
var contatore = function(callback) {
//do stuff here
callback();
}
var afterFinishedFunction = function(){
// this will execute when contatore finishes
}
// make it together
contatore(afterFinishedFunction); // (note, there is no brackets like this afterFinishedFunction()
8 Comments
callback() won't be called ? if //do stuff here have settimeout functioncallback() must be called at the end of setTimeout body function. You pass only the pointer to function as argument.//do stuff here have settimeout of 10 sec. then callback(); will be called within 10 sec right ?callback(); at the end of setTimeout(function(){ //do stuff here callback() },10000);use await
function rocketLaunch(){
await contatore();
document.getElementById("imgRazzo").src = imgRazzoAcceso.src;
}
Demo on how it works
function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
async function demo() {
console.log('Taking a break...');
await sleep(2000);
console.log('Two second later');
}
demo();
Syntax of sleep is taken from this link
5 Comments
whilesleep is taken from this link. which browser u are using?You could do it with a callback, like this:
// dummy image, just for this demo:
var imgRazzoAcceso = {
src: 'https://cdn.pixabay.com/photo/2014/04/03/11/58/rocket-312767_1280.png'
};
function rocketLaunch(){
contatore(10, function () { // callback
document.getElementById("imgRazzo").src = imgRazzoAcceso.src;
});
}
function contatore(number, done){
document.getElementById("main").textContent = number;
if(number) {
// use bind for shorter syntax. Also a bit shorter delay for this demo :-)
setTimeout(contatore.bind(null, number - 1, done), 200);
} else {
// when all is done: call callback
done();
}
}
rocketLaunch();
body { font-size: 50px; text-align: center; }
<img id="imgRazzo" src="https://openclipart.org/download/261322/rocket-297573.svg" width="100px" height="100px"></img>
<div id="main"></div>
Comments
You can use Promise constructor, pass onFulfilled function reference to a function which calls setTimeout; if number is equal to 0 call onFulfilled to resolve the Promise, else recursively call setTimeout until number is equal to 0
var imgRazzoAcceso = {
src: "http://placehold.it/100x100"
}
function rocketLaunch() {
contatore(10)
.then(function() {
document.getElementById("imgRazzo").src = imgRazzoAcceso.src;
})
}
function checkNumber(n) {
return n == 0
}
function delay(number, resolve) {
console.log("delay", number);
setTimeout(function re() {
if (checkNumber(number - 1)) {
resolve()
} else {
delay(number - 1, resolve)
}
}, 1000);
}
function contatore(number) {
return new Promise(function(resolve) {
if (checkNumber(number)) {
resolve();
} else {
delay(number - 1, resolve)
}
})
}
rocketLaunch()
<img id="imgRazzo" alt="imgRazzo" />
contatoreis related to timeout or interval ??