Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

what is the Ember implementation of setInterval and clearInterval

Tags:

ember.js

Ember has the following implementation of setTimeout, which it is recommended developers use because the code gets added to the run loop, which has advantages for tests.

           Ember.run.later((function() {
               console.log("will run once after 1000");
           }), 1000); 

Is there a similar Ember replacement for setInterval and, by implication, clearInterval (which is used to cancel a setInterval)? I need to run someFunc every 1000 ms

this.intervalId = setInterval(this.someFunc.bind(this), 1000);
like image 967
Leahcim Avatar asked Feb 03 '15 22:02

Leahcim


3 Answers

I'm not aware of any equivalent, but I use such a code to have the functionality:

var Poller = Ember.Object.extend({

  _interval: 1000,
  _currentlyExecutedFunction: null,

  start: function(context, pollingFunction) {
    this.set('_currentlyExecutedFunction', this._schedule(context, pollingFunction, [].slice.call(arguments, 2)));
  },

  stop: function() {
    Ember.run.cancel(this.get('_currentlyExecutedFunction'));
  },

  _schedule: function(context, func, args) {
    return Ember.run.later(this, function() {
      this.set('_currentlyExecutedFunction', this._schedule(context, func, args));
      func.apply(context, args);
    }, this.get('_interval'));
  },

  setInterval: function(interval) {
    this.set('_interval', interval);
  }

});

export
default Poller;

Then, you instantiate the poller: var poller = Poller.create() and then you can play with poller.start() and poller.stop() + set set the interval via poller.setInterval(interval).

In my code, I did more or less that way (polling the reports every 10 seconds):

_updateRunningReport: function(report) {
  var poller = new Poller();
  poller.setInterval(this.POLLING_INTERVAL);
  poller.start(this, function() {
    if (report.isRunning()) {
      this._reloadReport(report);
    } else {
      poller.stop();
    }
  });
  eventBus.onLogout(function() {
    poller.stop();
  });
},

Hope this helps...

like image 123
andrusieczko Avatar answered Nov 10 '22 14:11

andrusieczko


I have been playing around with implement "setInterval" in Ember Octane way and I think this is THE MOST SIMPLE and CLEAN solution:

index.hbs:

{{this.counter}}
<button {{on "click" this.start}}>Start</button>
<button {{on "click" this.stop}}>Stop</button>
<button {{on "click" this.reset}}>Reset</button>

controllers/index.js

import Controller from '@ember/controller';
import { tracked } from '@glimmer/tracking';
import { action } from '@ember/object';
import { cancel, later, next } from '@ember/runloop';

export default class IndexController extends Controller {
  @tracked counter = 0;
  runner = null;

  @action start() {
    next(this, function () {
      this.runner = this.tick();
    });
  }

  @action stop() {
    cancel(this.runner);
  }

  @action reset() {
    this.counter = 0;
  }

  tick() {
    return later(this, function () {
      this.counter++;
      this.runner = this.tick();
    }, 1000);
  }    
}

result in browser

like image 26
needprayfornotaxes Avatar answered Nov 10 '22 15:11

needprayfornotaxes


Another option is to use the ember-poll add-on. Internally, it does somewhat the same as @andrusieczko Poller object (both take the Ember Run Loop into account). From an Ember developer view, you get access to a poll service.

Just install the add-on: npm install ember-poll --save-dev.


Example:

import Ember from 'ember';

export default Ember.Route.extend({
  poll: Ember.service.inject(),

  setupController() {
    this._super(...arguments);

    this.get('poll').addPoll({
      interval: 1000,
      label: 'my-poll',
      callback: () => {
        //do something every second
      }
    }); 
  },

  actions: {
    willTransition() {
      this.get('poll').clearPollByLabel('my-poll');
    }
  }
}
like image 1
Jacob van Lingen Avatar answered Nov 10 '22 14:11

Jacob van Lingen