所以几个月前我开始在这家公司工作,我被要求每隔一天发送预定的电子邮件,关于在特定时间范围内反复出现问题的机器。我之前的开发人员创建了一个脚本来执行此操作,但是他决定如何实现它存在一些问题。它的实现方式是,他决定使用 node-shceduler 为这些预定的电子邮件创建一个组件,并且该组件正在主组件渲染方法中呈现,对我来说这是一个很大的危险信号。问题是,每当渲染这个主组件时,计划的脚本也会运行,并且在主组件中调用 setState 的所有时间,脚本组件都会被渲染并阻塞系统。
我意识到这是非常低效的,我觉得可以做得更好。我的主要想法是将这个调度方法放在服务器端,但问题是我不确定如何将我的数据从数据库获取到服务器来执行此操作。
这是我的 Timedscripts.js 文件
export default class Timedscripts extends React.Component{
constructor(props) {
super(props);
this.state = {
count: 0,
};
}
TimedScript(email){
let logs = this.props.logs;
let temp = [];
for(let j = 0; j < logs.length; j++){
if(logs[j].KioskID != 'Testing'){
temp.push(logs[j].KioskID)
}
}
let uniq = [... new Set(temp)];
let hash = [];
for(let i = 0; i < uniq.length; i++){
let count = 0;
for(let j = 0; j < temp.length; j++){
if(temp[j] == uniq[i]){
count = count + 1;
}
}
hash.push(count);
}
let results = [];
for(let k = 0; k < hash.length; k++){
if(hash[k] >= 2){
results.push(uniq[k]);
}
}
if(this.state.count3 == 0){
var r = schedule.scheduleJob('0 19 * * *', function(){ // schedule for 7pm everyday
if(results.length != 0){
var arrayToEmail = [];
for(var l = 0; l < results.length; l++){
arrayToEmail.push(results[l] + '\n')
}
var to = email;
var text =
`<div width="100%",style="text-align:left;">` +
`<h1 style="text-align:center;">Machines With Reccuring Issues</h1>` +
`<table border="1", width="100%">` +
`<tbody style="text-align:left;">` +
`<tr><td width="300">Machine(s) that have had 2 or more issues within the last 30 days.</td></tr>` +
arrayToEmail +
`</tbody>` +
`</table >` +
`</div >`;
console.log("Sending Email")
$.get("/send", { to: to, subject: 'Machines to Watch', text: text }, function (data) { });
}
})
this.setState({count: 1})
}
}
render(){
return(
<div>
<button id="30Days" onClick={() => this.TimedScript(this.props.msgList.EmailTo)} style={{display: 'none'}}></button>
</div>
);
}
}
我发现该计数用于阻止此模块创建与主组件渲染一样多的电子邮件,这在 imo 中再次看起来非常糟糕。'/send' 从服务器端发送一封电子邮件。
这是主要组件
export default class MainComponent extends React.Component{
... some methods and such
render(){
return(
<div>
...some html
<TimedScripts logs={this.state.LogHistory} inventoryItems={this.props.inventoryItems} alerts={this.props.alerts} issues={this.props.issues} info={this.props.kiosksInfo} starPaper={this.props.starPaper} msgList={this.props.msgList} completedJobs={this.props.completedJobs}/>
script{
setTimeout(function(){
$('#30Days').trigger('click')
}, 5000)
}
</div>
);
}
}
如您所见,每次渲染主组件时,此脚本组件都会安装并一遍又一遍地运行它的方法。
我通过调用主组件中的套接字获得所需的信息,然后调用 db 过程,然后将此信息传递到 TimedScripts 组件。如果有人对我如何使该组件渲染一次有想法,或者如果有更好更有效的方法来做到这一点,我将不胜感激!谢谢。