Understanding while-loops in Vue with setTimeout
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
add a comment |
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
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
add a comment |
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
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
javascript vue.js
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
add a comment |
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
add a comment |
2 Answers
2
active
oldest
votes
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
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 calltest
either with an initial value of0
or use0
as a default value for thecounter
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 wholewhile if for
messy stuff
– Badgy
Nov 15 '18 at 11:00
|
show 1 more comment
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();
}
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
add a comment |
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
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
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
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 calltest
either with an initial value of0
or use0
as a default value for thecounter
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 wholewhile if for
messy stuff
– Badgy
Nov 15 '18 at 11:00
|
show 1 more comment
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
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 calltest
either with an initial value of0
or use0
as a default value for thecounter
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 wholewhile if for
messy stuff
– Badgy
Nov 15 '18 at 11:00
|
show 1 more comment
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
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
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 calltest
either with an initial value of0
or use0
as a default value for thecounter
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 wholewhile if for
messy stuff
– Badgy
Nov 15 '18 at 11:00
|
show 1 more comment
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 calltest
either with an initial value of0
or use0
as a default value for thecounter
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 wholewhile 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
|
show 1 more comment
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();
}
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
add a comment |
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();
}
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
add a comment |
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();
}
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();
}
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
add a comment |
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
add a comment |
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.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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
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