Подтвердить что ты не робот

SetTimeout против Ember.run.later в приложении ember?

Внутри моего шаблона ручек:

Today date: {{currentDate}}
Current Time: {{currentTime}}

Внутри моих помощников:

Ember.Handlebars.registerBoundHelper 'currentDate', (option) ->
  moment().format('LL');

Ember.Handlebars.registerBoundHelper 'currentTime', (option) ->
  moment().format('h:mm:ss a');

Как я могу обновить currentTime до представления каждые 1 секунду?

Я читал, что Ember рекомендует Ember.run.later, но я не могу понять, куда его поместить и как его называть этот помощник.

4b9b3361

Ответ 1

Вы можете использовать ember.run.later, как обычно, вы используете setTimeout

Ember.run.later((function() {
  //do something in here that will run in 2 seconds
}), 2000);

Я не изнутри, но я знаю, что для интеграционного тестирования ember требуется использовать run.later(если тестовый код не будет ждать окончания таймаута)

Ответ 2

Вы не захотите добавить тайм-аут в помощник, вы хотите добавить его в глобальную переменную и просто выполнить diff от него. Причина, по которой вы захотите использовать Em.run.later, - это ввести ее в цикл выполнения (часть того, что получал Торан). Это действительно важно для тестирования.

Добавьте время к глобальной переменной

App.ApplicationRoute = Em.Route.extend({
  setupController: function(controller, model){
    this._super(controller, model);
    this.startWatchingTime(controller);
  },
  startWatchingTime: function(controller){
    var self = this;
    controller.set('currentTime', moment());
    Em.run.later(function(){
      self.startWatchingTime(controller);
    }, 1000);
  }
});

Добавьте его в помощник

Ember.Handlebars.helper('time-diff', function(date1, date2, format, options) {
  return date1.diff(date2, format);
});

отправить его в помощник

{{time-diff  controllers.application.currentTime anotherTime 'seconds'}}

http://emberjs.jsbin.com/UcUrIQa/1/edit

Ответ 3

вы хотите использовать цикл Embers.run вместо выхода с помощью setTimer.

Текущая (сегодняшняя) версия ember требует этого формата с context this (обновление ответа Toran Billups)

this._debouncedItem = Ember.run.later(this, () => {
   debugger;
}, 5000);

Я настоятельно рекомендую сохранить ссылку на ответ later() и отменить его в destroy hook

destroy() {
   this._super(...arguments);
   Ember.run.cancel(this._debouncedItem);
},

Ответ 4

Вы можете сделать currentDate регулярное свойство

currentDate: null,
currentTime: null

Вы можете запустить этот таймер в конструкторе контроллера.

init: function () { 
  this.updateTimeProperty();
},
updateTimeProperty: function () {
  var _this = this;
  Ember.run.later(this, function() {
    _this.currentDate = moment().format('LL');
    _this.set('currentTime',  moment().format('h:mm:ss a');
    _this.updateTimeProperty());
  }, 1000);
}

Ответ 5

Я немного устарел. Пользователь Ember, но я бы сделал это, как эта надежда, есть лучшее решение.

App.CurrentTimeView = Ember.View.extend({
    template : Ember.Handlebars.compile("<span>{{view.currentTime}}</span>"),
    currentTime : null,
    init : function(){
        var view = this;
        view.set('currentTime', moment().format('h:mm:ss a'));
        setInterval((function(view){
            return function(){view.set('currentTime', moment().format('h:mm:ss a'));};
        })(view),1000);
    }
});

и в шаблоне

{{view "App.CurrentTimeView"}}

Чтобы ответить на ваш вопрос, Javascript имеет однопоточное выполнение (если вы не используете веб-мастеров), что означает, что он будет делать вещи один за другим в последовательном порядке. Когда вы используете setInterval, он будет запускать вашу функцию каждые x миллисекунды в эту основную очередь выполнения. setInterval использует пройденный time для выполнения своей очереди. Циклы запуска Ember будут сортировать привязки и другие тяжелые вещи в каждом цикле цикла, поэтому в конце цикла мы уверены, что изменения уже готовы. Есть крючки, такие как Em.run.next, чтобы убедиться, что эти коды при запуске будут иметь полные изменения, выполненные в последнем цикле выполнения. Аналогично, когда вы передаете время Em.run.later, он также будет работать после этого много времени, а также поддерживает параметр для установки this внутри функции. В основном, имея дело с некоторыми переменными или данными Model/Controller внутри функции.

В вашем случае setInterval выглядит нормально (для меня).

http://jsfiddle.net/NQKvy/604/