我是否以低效的方式使用 setTimeout?
Am I using setTimeout in an inefficient manner?
我有一个 angular 应用程序,我想实现一个 'Time Ago' 功能。如果我渲染一些疯狂的 'questions',这会是个坏主意吗?
如果你能想象一个 facebook post 上面写着 'posted about a minute ago...',这就是我的目标。
假设用户从未刷新过页面,并且问题附加到来自 signlar hub
的 angular 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...
}
}
我不知道有很多setTimeout调用的性能影响是什么,但我宁愿将timeAgo
设置为一个日期对象,然后检查now
和那个之间的区别每当更新 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()
}
}
我不使用Typescript,不知道语法是否正确。例如,正如下面提到的评论之一所述,最好使用访问器 (getter
).
好的,newQuestion
和第一个 setTimeout
只是样板代码,可以用来测试一些东西。请忽略。第二个 setInteval 是我们查看 data
属性的地方。此属性符合 HTML 标准。并且可以通过 [HTMLElement].dataset
访问。我们测试我们的 post 时间对照电流。在一个单一的方法。
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>
我有一个 angular 应用程序,我想实现一个 'Time Ago' 功能。如果我渲染一些疯狂的 'questions',这会是个坏主意吗?
如果你能想象一个 facebook post 上面写着 'posted about a minute ago...',这就是我的目标。
假设用户从未刷新过页面,并且问题附加到来自 signlar hub
的 angular mdoelexport 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...
}
}
我不知道有很多setTimeout调用的性能影响是什么,但我宁愿将timeAgo
设置为一个日期对象,然后检查now
和那个之间的区别每当更新 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()
}
}
我不使用Typescript,不知道语法是否正确。例如,正如下面提到的评论之一所述,最好使用访问器 (getter
).
好的,newQuestion
和第一个 setTimeout
只是样板代码,可以用来测试一些东西。请忽略。第二个 setInteval 是我们查看 data
属性的地方。此属性符合 HTML 标准。并且可以通过 [HTMLElement].dataset
访问。我们测试我们的 post 时间对照电流。在一个单一的方法。
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>