简体   繁体   中英

Am I using setTimeout in an inefficient manner?

I have an angular app and I want to implement a 'Time Ago' feature. If I render some crazy number of 'questions', would this be a bad idea?

If you can imagine a facebook post that says 'posted about a minute ago...', that's what I'm shooting for.

The assumption is that the user never refreshed the page and the questions are appended to the angular mdoel from a signlar hub

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...
  }
}

I don't know what the performance effect of having many setTimeout calls is, but I would rather set timeAgo to be a date object, and then check the difference between now and that date object whenever updating the UI:

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()
  }
}

I don't know if the syntax is correct since I don't use Typescript. For example, as one of the comments mentioned below states it would be better to use an accessor ( getter ).

Ok, newQuestion and the first setTimeout are only boilerplate code to get something working to test. Please ignore. The second setInteval is where we look at our data attribute. This attribute is HTML standard compliant. and can be accessed through [HTMLElement].dataset . We test our post time against current. In a single method.

 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> 

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