Understanding while-loops in Vue with setTimeout












1















I'm quite new with Vue. This is confusing the hell out of me.



If I have this while-loop inside of a method.



methods: {
test: function() {
counter = 0;
while( counter < 10 ){
console.log( counter );
counter++;
window.setTimeout( function() {
console.log( 'Test' );
}, 1000)
}
}
},
mounted() {
this.test();
}


Then in my console, it will print this:



0
1
2
3
4
5
6
7
8
9

(10) Test


Correct me if I'm wrong, but shouldn't it write this:



0
Test
1
Test
2
Test
3
Test
4
Test
5
Test
6
Test
7
Test
8
Test
9
Test


... And do it with a seconds delay in-between?



The reason why I'm asking is that I'm pulling data from an API, - and only want to initialize a function, when the data has been populated.



This post, suggest using arrow-functions for the setTimeout, but I'm not seeing any difference when doing it.



And I've looked a lot at Vue's lifecycle, but that didn't show me the answer either.










share|improve this question























  • setTimeout does not stop execution of the code. Imagine setting a timeout as setting a kitchen timer; the browser will still do stuff (in this case, continue the while loop) while it waits for the timer to go off.

    – puddi
    Nov 15 '18 at 10:45











  • You might also want to read up on JavaScript Promises and async/await. Especially if you're doing API calls you usually want to wait with your function execution until the call has finished. Promises give you an easy and standardised way to do so. This example might be relevant to your current case.

    – Padarom
    Nov 15 '18 at 11:02


















1















I'm quite new with Vue. This is confusing the hell out of me.



If I have this while-loop inside of a method.



methods: {
test: function() {
counter = 0;
while( counter < 10 ){
console.log( counter );
counter++;
window.setTimeout( function() {
console.log( 'Test' );
}, 1000)
}
}
},
mounted() {
this.test();
}


Then in my console, it will print this:



0
1
2
3
4
5
6
7
8
9

(10) Test


Correct me if I'm wrong, but shouldn't it write this:



0
Test
1
Test
2
Test
3
Test
4
Test
5
Test
6
Test
7
Test
8
Test
9
Test


... And do it with a seconds delay in-between?



The reason why I'm asking is that I'm pulling data from an API, - and only want to initialize a function, when the data has been populated.



This post, suggest using arrow-functions for the setTimeout, but I'm not seeing any difference when doing it.



And I've looked a lot at Vue's lifecycle, but that didn't show me the answer either.










share|improve this question























  • setTimeout does not stop execution of the code. Imagine setting a timeout as setting a kitchen timer; the browser will still do stuff (in this case, continue the while loop) while it waits for the timer to go off.

    – puddi
    Nov 15 '18 at 10:45











  • You might also want to read up on JavaScript Promises and async/await. Especially if you're doing API calls you usually want to wait with your function execution until the call has finished. Promises give you an easy and standardised way to do so. This example might be relevant to your current case.

    – Padarom
    Nov 15 '18 at 11:02
















1












1








1








I'm quite new with Vue. This is confusing the hell out of me.



If I have this while-loop inside of a method.



methods: {
test: function() {
counter = 0;
while( counter < 10 ){
console.log( counter );
counter++;
window.setTimeout( function() {
console.log( 'Test' );
}, 1000)
}
}
},
mounted() {
this.test();
}


Then in my console, it will print this:



0
1
2
3
4
5
6
7
8
9

(10) Test


Correct me if I'm wrong, but shouldn't it write this:



0
Test
1
Test
2
Test
3
Test
4
Test
5
Test
6
Test
7
Test
8
Test
9
Test


... And do it with a seconds delay in-between?



The reason why I'm asking is that I'm pulling data from an API, - and only want to initialize a function, when the data has been populated.



This post, suggest using arrow-functions for the setTimeout, but I'm not seeing any difference when doing it.



And I've looked a lot at Vue's lifecycle, but that didn't show me the answer either.










share|improve this question














I'm quite new with Vue. This is confusing the hell out of me.



If I have this while-loop inside of a method.



methods: {
test: function() {
counter = 0;
while( counter < 10 ){
console.log( counter );
counter++;
window.setTimeout( function() {
console.log( 'Test' );
}, 1000)
}
}
},
mounted() {
this.test();
}


Then in my console, it will print this:



0
1
2
3
4
5
6
7
8
9

(10) Test


Correct me if I'm wrong, but shouldn't it write this:



0
Test
1
Test
2
Test
3
Test
4
Test
5
Test
6
Test
7
Test
8
Test
9
Test


... And do it with a seconds delay in-between?



The reason why I'm asking is that I'm pulling data from an API, - and only want to initialize a function, when the data has been populated.



This post, suggest using arrow-functions for the setTimeout, but I'm not seeing any difference when doing it.



And I've looked a lot at Vue's lifecycle, but that didn't show me the answer either.







javascript vue.js






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Nov 15 '18 at 10:41









ZethZeth

70011532




70011532













  • setTimeout does not stop execution of the code. Imagine setting a timeout as setting a kitchen timer; the browser will still do stuff (in this case, continue the while loop) while it waits for the timer to go off.

    – puddi
    Nov 15 '18 at 10:45











  • You might also want to read up on JavaScript Promises and async/await. Especially if you're doing API calls you usually want to wait with your function execution until the call has finished. Promises give you an easy and standardised way to do so. This example might be relevant to your current case.

    – Padarom
    Nov 15 '18 at 11:02





















  • setTimeout does not stop execution of the code. Imagine setting a timeout as setting a kitchen timer; the browser will still do stuff (in this case, continue the while loop) while it waits for the timer to go off.

    – puddi
    Nov 15 '18 at 10:45











  • You might also want to read up on JavaScript Promises and async/await. Especially if you're doing API calls you usually want to wait with your function execution until the call has finished. Promises give you an easy and standardised way to do so. This example might be relevant to your current case.

    – Padarom
    Nov 15 '18 at 11:02



















setTimeout does not stop execution of the code. Imagine setting a timeout as setting a kitchen timer; the browser will still do stuff (in this case, continue the while loop) while it waits for the timer to go off.

– puddi
Nov 15 '18 at 10:45





setTimeout does not stop execution of the code. Imagine setting a timeout as setting a kitchen timer; the browser will still do stuff (in this case, continue the while loop) while it waits for the timer to go off.

– puddi
Nov 15 '18 at 10:45













You might also want to read up on JavaScript Promises and async/await. Especially if you're doing API calls you usually want to wait with your function execution until the call has finished. Promises give you an easy and standardised way to do so. This example might be relevant to your current case.

– Padarom
Nov 15 '18 at 11:02







You might also want to read up on JavaScript Promises and async/await. Especially if you're doing API calls you usually want to wait with your function execution until the call has finished. Promises give you an easy and standardised way to do so. This example might be relevant to your current case.

– Padarom
Nov 15 '18 at 11:02














2 Answers
2






active

oldest

votes


















1














Counting in the while loop happens really fast (< 1 second), so by the time the timeout executes the rest of your while loop has already executed (printing 0 to 9), after that your timeouts reach their countdown and also print 'Test' consecutively. This causes it to be printed 10 times after each other which in the console is abbreviated with the prefix (10) instead of printing test literally 10 times.



This happens because when you call window.setTimeout the code called here will be executed after x miliseconds in parallel, thus the rest of your code continues to process while the timeout is counting down.



If you want the result you expected you should execute it directly and not use a timeout:



methods: {
test: function() {
counter = 0;
while( counter < 10 ){
console.log( counter );
counter++;
console.log( 'Test' );
}
}
},
mounted() {
this.test();
}


If you want to wait 1 second between every number you should use a recursive function, something like this:



test(0);

function test (counter) {
if (counter < 10) {
console.log( counter );
counter++;
console.log( 'Test' );
window.setTimeout( function() {
test(counter);
}, 1000)
}
}


Make sure to use an initial or default value of 0 for this






share|improve this answer


























  • Thanks for your input. But I'm after a function that executes once every second. How do I stop/pause the execution of the next while-loop?

    – Zeth
    Nov 15 '18 at 10:55






  • 1





    @Zeth, I updated the answer, if anything is unclear please let me know :)

    – Sven Hakvoort
    Nov 15 '18 at 10:56











  • In that case make sure to call test either with an initial value of 0 or use 0 as a default value for the counter argument.

    – Padarom
    Nov 15 '18 at 10:57











  • @Padarom, yes of course :). But you're right, that might be good to add to the answer. I updated my answer

    – Sven Hakvoort
    Nov 15 '18 at 10:58






  • 1





    I would suggest an Async solution specially because he fetches something from the API instead of this whole while if for messy stuff

    – Badgy
    Nov 15 '18 at 11:00



















0














The best you can use is a Promise. The getApi function should be modified and read the API and using a promise to execute it in parallel, so I would call the then once the load is finished...



methods: {
test: function() {
this.getAPI().then((data) => {
// here is the API load finished | data === 'example data'
});
},
getAPI: function(){
// change this
return new Promise((resolve) => {
resolve('example data');
});
}

},
mounted() {
this.test();
}





share|improve this answer
























  • This does not answer the question of the OP completely, would you consider also adding an explanation of how a delay between the API calls can be achieved correctly? Because this is an important part of the question

    – Sven Hakvoort
    Nov 15 '18 at 11:53











Your Answer






StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");

StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});














draft saved

draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53317581%2funderstanding-while-loops-in-vue-with-settimeout%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown

























2 Answers
2






active

oldest

votes








2 Answers
2






active

oldest

votes









active

oldest

votes






active

oldest

votes









1














Counting in the while loop happens really fast (< 1 second), so by the time the timeout executes the rest of your while loop has already executed (printing 0 to 9), after that your timeouts reach their countdown and also print 'Test' consecutively. This causes it to be printed 10 times after each other which in the console is abbreviated with the prefix (10) instead of printing test literally 10 times.



This happens because when you call window.setTimeout the code called here will be executed after x miliseconds in parallel, thus the rest of your code continues to process while the timeout is counting down.



If you want the result you expected you should execute it directly and not use a timeout:



methods: {
test: function() {
counter = 0;
while( counter < 10 ){
console.log( counter );
counter++;
console.log( 'Test' );
}
}
},
mounted() {
this.test();
}


If you want to wait 1 second between every number you should use a recursive function, something like this:



test(0);

function test (counter) {
if (counter < 10) {
console.log( counter );
counter++;
console.log( 'Test' );
window.setTimeout( function() {
test(counter);
}, 1000)
}
}


Make sure to use an initial or default value of 0 for this






share|improve this answer


























  • Thanks for your input. But I'm after a function that executes once every second. How do I stop/pause the execution of the next while-loop?

    – Zeth
    Nov 15 '18 at 10:55






  • 1





    @Zeth, I updated the answer, if anything is unclear please let me know :)

    – Sven Hakvoort
    Nov 15 '18 at 10:56











  • In that case make sure to call test either with an initial value of 0 or use 0 as a default value for the counter argument.

    – Padarom
    Nov 15 '18 at 10:57











  • @Padarom, yes of course :). But you're right, that might be good to add to the answer. I updated my answer

    – Sven Hakvoort
    Nov 15 '18 at 10:58






  • 1





    I would suggest an Async solution specially because he fetches something from the API instead of this whole while if for messy stuff

    – Badgy
    Nov 15 '18 at 11:00
















1














Counting in the while loop happens really fast (< 1 second), so by the time the timeout executes the rest of your while loop has already executed (printing 0 to 9), after that your timeouts reach their countdown and also print 'Test' consecutively. This causes it to be printed 10 times after each other which in the console is abbreviated with the prefix (10) instead of printing test literally 10 times.



This happens because when you call window.setTimeout the code called here will be executed after x miliseconds in parallel, thus the rest of your code continues to process while the timeout is counting down.



If you want the result you expected you should execute it directly and not use a timeout:



methods: {
test: function() {
counter = 0;
while( counter < 10 ){
console.log( counter );
counter++;
console.log( 'Test' );
}
}
},
mounted() {
this.test();
}


If you want to wait 1 second between every number you should use a recursive function, something like this:



test(0);

function test (counter) {
if (counter < 10) {
console.log( counter );
counter++;
console.log( 'Test' );
window.setTimeout( function() {
test(counter);
}, 1000)
}
}


Make sure to use an initial or default value of 0 for this






share|improve this answer


























  • Thanks for your input. But I'm after a function that executes once every second. How do I stop/pause the execution of the next while-loop?

    – Zeth
    Nov 15 '18 at 10:55






  • 1





    @Zeth, I updated the answer, if anything is unclear please let me know :)

    – Sven Hakvoort
    Nov 15 '18 at 10:56











  • In that case make sure to call test either with an initial value of 0 or use 0 as a default value for the counter argument.

    – Padarom
    Nov 15 '18 at 10:57











  • @Padarom, yes of course :). But you're right, that might be good to add to the answer. I updated my answer

    – Sven Hakvoort
    Nov 15 '18 at 10:58






  • 1





    I would suggest an Async solution specially because he fetches something from the API instead of this whole while if for messy stuff

    – Badgy
    Nov 15 '18 at 11:00














1












1








1







Counting in the while loop happens really fast (< 1 second), so by the time the timeout executes the rest of your while loop has already executed (printing 0 to 9), after that your timeouts reach their countdown and also print 'Test' consecutively. This causes it to be printed 10 times after each other which in the console is abbreviated with the prefix (10) instead of printing test literally 10 times.



This happens because when you call window.setTimeout the code called here will be executed after x miliseconds in parallel, thus the rest of your code continues to process while the timeout is counting down.



If you want the result you expected you should execute it directly and not use a timeout:



methods: {
test: function() {
counter = 0;
while( counter < 10 ){
console.log( counter );
counter++;
console.log( 'Test' );
}
}
},
mounted() {
this.test();
}


If you want to wait 1 second between every number you should use a recursive function, something like this:



test(0);

function test (counter) {
if (counter < 10) {
console.log( counter );
counter++;
console.log( 'Test' );
window.setTimeout( function() {
test(counter);
}, 1000)
}
}


Make sure to use an initial or default value of 0 for this






share|improve this answer















Counting in the while loop happens really fast (< 1 second), so by the time the timeout executes the rest of your while loop has already executed (printing 0 to 9), after that your timeouts reach their countdown and also print 'Test' consecutively. This causes it to be printed 10 times after each other which in the console is abbreviated with the prefix (10) instead of printing test literally 10 times.



This happens because when you call window.setTimeout the code called here will be executed after x miliseconds in parallel, thus the rest of your code continues to process while the timeout is counting down.



If you want the result you expected you should execute it directly and not use a timeout:



methods: {
test: function() {
counter = 0;
while( counter < 10 ){
console.log( counter );
counter++;
console.log( 'Test' );
}
}
},
mounted() {
this.test();
}


If you want to wait 1 second between every number you should use a recursive function, something like this:



test(0);

function test (counter) {
if (counter < 10) {
console.log( counter );
counter++;
console.log( 'Test' );
window.setTimeout( function() {
test(counter);
}, 1000)
}
}


Make sure to use an initial or default value of 0 for this







share|improve this answer














share|improve this answer



share|improve this answer








edited Nov 15 '18 at 10:57

























answered Nov 15 '18 at 10:52









Sven HakvoortSven Hakvoort

2,1602621




2,1602621













  • Thanks for your input. But I'm after a function that executes once every second. How do I stop/pause the execution of the next while-loop?

    – Zeth
    Nov 15 '18 at 10:55






  • 1





    @Zeth, I updated the answer, if anything is unclear please let me know :)

    – Sven Hakvoort
    Nov 15 '18 at 10:56











  • In that case make sure to call test either with an initial value of 0 or use 0 as a default value for the counter argument.

    – Padarom
    Nov 15 '18 at 10:57











  • @Padarom, yes of course :). But you're right, that might be good to add to the answer. I updated my answer

    – Sven Hakvoort
    Nov 15 '18 at 10:58






  • 1





    I would suggest an Async solution specially because he fetches something from the API instead of this whole while if for messy stuff

    – Badgy
    Nov 15 '18 at 11:00



















  • Thanks for your input. But I'm after a function that executes once every second. How do I stop/pause the execution of the next while-loop?

    – Zeth
    Nov 15 '18 at 10:55






  • 1





    @Zeth, I updated the answer, if anything is unclear please let me know :)

    – Sven Hakvoort
    Nov 15 '18 at 10:56











  • In that case make sure to call test either with an initial value of 0 or use 0 as a default value for the counter argument.

    – Padarom
    Nov 15 '18 at 10:57











  • @Padarom, yes of course :). But you're right, that might be good to add to the answer. I updated my answer

    – Sven Hakvoort
    Nov 15 '18 at 10:58






  • 1





    I would suggest an Async solution specially because he fetches something from the API instead of this whole while if for messy stuff

    – Badgy
    Nov 15 '18 at 11:00

















Thanks for your input. But I'm after a function that executes once every second. How do I stop/pause the execution of the next while-loop?

– Zeth
Nov 15 '18 at 10:55





Thanks for your input. But I'm after a function that executes once every second. How do I stop/pause the execution of the next while-loop?

– Zeth
Nov 15 '18 at 10:55




1




1





@Zeth, I updated the answer, if anything is unclear please let me know :)

– Sven Hakvoort
Nov 15 '18 at 10:56





@Zeth, I updated the answer, if anything is unclear please let me know :)

– Sven Hakvoort
Nov 15 '18 at 10:56













In that case make sure to call test either with an initial value of 0 or use 0 as a default value for the counter argument.

– Padarom
Nov 15 '18 at 10:57





In that case make sure to call test either with an initial value of 0 or use 0 as a default value for the counter argument.

– Padarom
Nov 15 '18 at 10:57













@Padarom, yes of course :). But you're right, that might be good to add to the answer. I updated my answer

– Sven Hakvoort
Nov 15 '18 at 10:58





@Padarom, yes of course :). But you're right, that might be good to add to the answer. I updated my answer

– Sven Hakvoort
Nov 15 '18 at 10:58




1




1





I would suggest an Async solution specially because he fetches something from the API instead of this whole while if for messy stuff

– Badgy
Nov 15 '18 at 11:00





I would suggest an Async solution specially because he fetches something from the API instead of this whole while if for messy stuff

– Badgy
Nov 15 '18 at 11:00













0














The best you can use is a Promise. The getApi function should be modified and read the API and using a promise to execute it in parallel, so I would call the then once the load is finished...



methods: {
test: function() {
this.getAPI().then((data) => {
// here is the API load finished | data === 'example data'
});
},
getAPI: function(){
// change this
return new Promise((resolve) => {
resolve('example data');
});
}

},
mounted() {
this.test();
}





share|improve this answer
























  • This does not answer the question of the OP completely, would you consider also adding an explanation of how a delay between the API calls can be achieved correctly? Because this is an important part of the question

    – Sven Hakvoort
    Nov 15 '18 at 11:53
















0














The best you can use is a Promise. The getApi function should be modified and read the API and using a promise to execute it in parallel, so I would call the then once the load is finished...



methods: {
test: function() {
this.getAPI().then((data) => {
// here is the API load finished | data === 'example data'
});
},
getAPI: function(){
// change this
return new Promise((resolve) => {
resolve('example data');
});
}

},
mounted() {
this.test();
}





share|improve this answer
























  • This does not answer the question of the OP completely, would you consider also adding an explanation of how a delay between the API calls can be achieved correctly? Because this is an important part of the question

    – Sven Hakvoort
    Nov 15 '18 at 11:53














0












0








0







The best you can use is a Promise. The getApi function should be modified and read the API and using a promise to execute it in parallel, so I would call the then once the load is finished...



methods: {
test: function() {
this.getAPI().then((data) => {
// here is the API load finished | data === 'example data'
});
},
getAPI: function(){
// change this
return new Promise((resolve) => {
resolve('example data');
});
}

},
mounted() {
this.test();
}





share|improve this answer













The best you can use is a Promise. The getApi function should be modified and read the API and using a promise to execute it in parallel, so I would call the then once the load is finished...



methods: {
test: function() {
this.getAPI().then((data) => {
// here is the API load finished | data === 'example data'
});
},
getAPI: function(){
// change this
return new Promise((resolve) => {
resolve('example data');
});
}

},
mounted() {
this.test();
}






share|improve this answer












share|improve this answer



share|improve this answer










answered Nov 15 '18 at 11:08









javimovijavimovi

318110




318110













  • This does not answer the question of the OP completely, would you consider also adding an explanation of how a delay between the API calls can be achieved correctly? Because this is an important part of the question

    – Sven Hakvoort
    Nov 15 '18 at 11:53



















  • This does not answer the question of the OP completely, would you consider also adding an explanation of how a delay between the API calls can be achieved correctly? Because this is an important part of the question

    – Sven Hakvoort
    Nov 15 '18 at 11:53

















This does not answer the question of the OP completely, would you consider also adding an explanation of how a delay between the API calls can be achieved correctly? Because this is an important part of the question

– Sven Hakvoort
Nov 15 '18 at 11:53





This does not answer the question of the OP completely, would you consider also adding an explanation of how a delay between the API calls can be achieved correctly? Because this is an important part of the question

– Sven Hakvoort
Nov 15 '18 at 11:53


















draft saved

draft discarded




















































Thanks for contributing an answer to Stack Overflow!


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53317581%2funderstanding-while-loops-in-vue-with-settimeout%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

Florida Star v. B. J. F.

Error while running script in elastic search , gateway timeout

Adding quotations to stringified JSON object values