Я использую setTimeout неэффективным способом? - PullRequest
0 голосов
/ 19 января 2019

У меня есть угловое приложение, и я хочу реализовать функцию «Время назад».Если я приведу какое-то сумасшедшее количество «вопросов», будет ли это плохой идеей?

Если вы можете представить пост на Facebook, в котором написано «опубликовано около минуты назад ...», это то, что я снимаюfor.

Предполагается, что пользователь никогда не обновлял страницу, а вопросы добавлялись в угловой mdoel из сигнального узла

export interface IQuestion {
  timeAgo: string;
}

export class Question implements IQuestion {
  public timeAgo: string;
  constructor(question: IQuestion) {
    this.timeAgoTicker();
  }
  timeAgoTicker(): void {
    this.timeAgo = 'just now';
    setTimeout( () => this.timeAgo = 'about a minute ago', 10000);
    setTimeout( () => this.timeAgo = 'a couple of minutes ago', 20000);
    setTimeout( () => this.timeAgo = '5 minutes ago', 50000);
    // etc...
  }
}

Ответы [ 2 ]

0 голосов
/ 19 января 2019

Хорошо, newQuestion и первые setTimeout - это всего лишь шаблонный код, чтобы заставить что-то работать для тестирования.Пожалуйста, игнорируйте.Второй setInteval - это место, где мы смотрим на наш атрибут data.Этот атрибут соответствует стандарту HTML.и могут быть доступны через [HTMLElement].dataset.Мы проверяем время нашей публикации против текущей.В одном методе.

const newQuestion = () => {
  let target = document.querySelector('.questions');
  let question = document.createElement('div');
  question.className = 'question';
  question.setAttribute('data-question-date', Date.now());
  question.innerHTML = '<span>Test Question - <span><span class="age">Just Now</span>';
  target.appendChild(question);
  
};

document.addEventListener('DOMContentLoaded', () => {
  setInterval(() => {
    newQuestion();
  }, 5000); 
  
  setInterval(() => {
    let questions = document.querySelectorAll('.question');
    questions.forEach(q => {
      let dateofQ = q.dataset.questionDate;
      let age = Math.floor((Date.now() - dateofQ)/1000);
      console.log(`age: ${age}`); 
      let ageElement = q.querySelector('.age');
      //do just 20 secs, so we don't have to wait.
      if(age < 20) {
        ageElement.innerHTML = 'Just now';
      } else if (age < 300) {
        ageElement.innerHTML = 'Less than 5 minutes ago.';
      } else {
        ageElement.innerHTML = 'More than 5 minutes ago.';
      }
    });
    
  }, 1000);
});
<div class="questions">


</div>
0 голосов
/ 19 января 2019

Я не знаю, каково влияние на производительность многих вызовов setTimeout, но я бы предпочел установить timeAgo в качестве объекта даты, а затем проверять разницу между now и этим объектом даты при каждом обновлении пользовательского интерфейса. :

export interface IQuestion {
  createdAt: Date;
}

export class Question implements IQuestion {
  public createdAt: Date;
  constructor(question: IQuestion) {
    this.createdAt = new Date();
  }

  getAge(): String {
    return (new Date() - this.createdAt).toSomeStringAccordingToAge()
  }
}

Я не знаю, правильный ли синтаксис, поскольку я не использую Typescript. Например, как говорится в одном из комментариев, упомянутых ниже, было бы лучше использовать метод доступа (getter).

...