简体   繁体   中英

Meteor Collection.find() blocks the entire application during working

I try to display a loading alert on Meteor with modal package during loading of data.

'change .filterPieChart': function(evt){

    Modal.show('loadingModal');

    /* a little bit of work */
    var data = MyCollection.find().fetch(); // takes 3 or 4 seconds
    /* lot of work */

    Modal.hide('loadingModal');
}

Normally, the alert is displayed at the beginning of the function, and disappears at the end. But here, the alert appears only after the loading time of the MyCollection.find(), and then disappears just behind. How to display it at the beginning of the function ??

I tried to replace Modal.show with reactive variable, and the result is the same, the changing value of reactive variable is detect at the end of the function.

From what you describe, what probably happens is that the JS engine is busy doing your computation (searching through the collection), and indeed blocks the UI, whether your other reactive variable has already been detected or not.

A simple workaround would be to give some time for the UI to show your modal by delaying the collection search (or any other intensive computation), typically with a setTimeout :

Modal.show('loadingModal');

setTimeout(function () {
    /* a little bit of work */
    var data = MyCollection.find().fetch(); // takes 3 or 4 seconds
    /* lot of work */

    Modal.hide('loadingModal');
}, 500); // delay in ms

A more complex approach could be to decrease the delay to the bare minimum by using requestAnimationFrame

I think you need to use template level subscription + reactiveVar. It is more the meteor way and your code looks consistent. As i can see you do some additional work ( retrive some data ) on the change event. Make sense to actually really retrive the data on the event instead of simulation this.

  Template.TemplateName.onCreated(function () {
    this.subsVar = new RelativeVar();
    this.autorun( () => {
      let subsVar = this.subsVar.get();
      this.subscribe('publicationsName', this.subsVar);    
    })
  })

  Template.TemplateName.events({
    'change .filterPieChart': function(evt){
      Template.instance().collectionDate.subsVar.set('value');
      Modal.show('loadingModal');

      MyCollection.find().fetch();    

      Modal.hide('loadingModal');
    }
  })

Please pay attention that i didn't test this code. And you need to use the es6 arrow function.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM