Reputation: 41949
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);
Upvotes: 8
Views: 5862
Reputation: 131
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);
}
}
Upvotes: 3
Reputation: 1865
Tested in ember -v 1.18
This is what I've been doing inside my component. This works perfectly fine and should be the ideal way of approaching. If you're handling async promise objects inside the interval, make sure to kill it in willDestroyElement()
hook or somewhere.
init() {
this._super(...arguments);
this.startAutoSaveTimer();
},
startAutoSaveTimer() {
let autosaveFunc = function() {
console.info('Arr .. I'm a pirate!');
};
set(this, 'timerInstance', setInterval(autosaveFunc, 1000));
},
Upvotes: 0
Reputation: 9537
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');
}
}
}
Upvotes: 1
Reputation: 2824
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...
Upvotes: 9