Skip to content

Computed properties calculation results are inconsistent #1162

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
fychinesepjj126 opened this issue Aug 15, 2015 · 3 comments
Closed

Computed properties calculation results are inconsistent #1162

fychinesepjj126 opened this issue Aug 15, 2015 · 3 comments

Comments

@fychinesepjj126
Copy link

Different code sequence have different computed result

  • Is the problem caused by the cache ?
  • Suggest having a switch to control the cache

_we want the result is example 1_
example 1 , console.log results:
0------old data
1------new data

example 2 , console.log results:
0------old data
1------old data
1------new data

<div id="demo">
    <button v-on="click:readContent">read</button>
    <test-content content="{{content}}" v-ref="test"  inline-template>
        <div>  {{ detailContent }}</div>
    </test-content>
</div>

Example 1: the results we want

Vue.config.debug =true;
vue = new Vue({
    el: '#demo',
    data: {
        content: 'old data'
    },
    methods:{
        readContent: function(){
            var self = this;

           setTimeout(function(){
                self.content = 'new data'; // set new content
                self.$.test.index = 1;   // set new index
            },2000);
        }
    },
    components: {
        'test-content': {
            props:['content'],
            data: function(){
                return {
                    index: 0
                }
            },
            computed: {
                detailContent: function(){
                    var tmp = this.index + '------' + this.content;
                    console.log(tmp);
                    return tmp;
                }
            }
        }
    }
})

example 2:

Vue.config.debug =true;
vue = new Vue({
    el: '#demo',
    data: {
        content: 'old data'
    },
    methods:{
        readContent: function(){
            var self = this;

           setTimeout(function(){
                self.$.test.index = 1;         // The code sequence is different 
                self.content = 'new data'; 
            },2000);
        }
    },
    components: {
        'test-content': {
            props:['content'],
            data: function(){
                return {
                    index: 0
                }
            },
            computed: {
                detailContent: function(){
                    var tmp = this.index + '------' + this.content;
                    console.log(tmp);
                    return tmp;
                }
            }
        }
    }
})
@yyx990803
Copy link
Member

Note the fix for this will be reverted in 1.0.0. The reason is that

  1. Users should not care about how computed properties getters are called, because by definition computed property getter are pure and have no side effects.
  2. The behavior demonstrated here has to do with how Vue's internal async update queue works. Vue relies on the async update queue to ensure correct behavior where it actually matters, for example, The _initData extremely slow since upgrade to Vue 0.12.11 from 0.12.10 #1226 & Prop validation occurring before a v-if #1262 .

@fychinesepjj126
Copy link
Author

Although the top two examples has the same result: 1------new data,
It still has a performance problem.

I modified the example:
the new result:
0------old data ---wait 3s
1------old data ---wait 3s (unnecessary calculation)
1------new data ---wait 3s

It will spend more time than before ( sync: true)

How to reduce the performance problem caused by the computed properties re-evaluated in this case?

Vue.config.debug =true;
vue = new Vue({
    el: '#demo',
    data: {
        content: 'old data'
    },
    methods:{
        readContent: function(){
            var self = this;

           setTimeout(function(){
                self.$.test.index = 1;
                self.content = 'new data'; 
            },2000);
        }
    },
    components: {
        'test-content': {
            props:['content'],
            data: function(){
                return {
                    index: 0
                }
            },
            computed: {
                detailContent: function(){

                    //more waste of time
                    /***************************/
                    var start = +new Date();
                    var end = start + 3000; // +3s
                    while(start < end){
                        start = +new Date();
                    }
                    var tmp = this.index + '------' + this.content;
                    console.log(tmp);
                    return tmp;
                }
            }
        }
    }
}) 

@yyx990803
Copy link
Member

It's only a performance problem if it actually slows down your app. Simple computed properties are very fast to evaluate and the extra calls are an ok tradeoff to ensure correctness of the while system. If you have a real case where this behavior is the cause of a noticeable performance issue, then we'll consider fixing it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants