国庆长假马上就要结束了,可能有些同学都快把腰玩坏了,有些同学也宅出了新境界,那么面对即将到来的双十一,是否做好了继续“剁手”的准备,或者勇敢的向前一小步,解放双手;好吧,其实我只是想说:假期,你别走!
放假前,激情澎湃的定了一堆计划,要去哪哪好好逛逛,怎么怎么任性一把,要学学Angular2、巩固巩固React、瞄一瞄Vue,耍一耍ES6(看看我这对学习难以抑制的热情!);现在看来,只有梦想最美,现实里早已现原形——“行动的矮子”;于是我给未来的自己发了一封邮件:“珍惜现在吧,未来会更糟!”;当然,我只是个反面例子,希望大家都能做个语言的巨人,行动的巨人并且珍惜现在,勇敢向前!
慢邮:给未来的自己!
慢邮,说白了就是一种定时邮件服务;其实这玩意儿本身并不高大上,只有很少的不太火的公司在做这个,个人只是感觉其中有些情怀还是值得拥有的,毕竟人总会有心累的时候,这时你可能需要一碗“鸡汤”或是喝点“鸡血”,当然也不排除其他刺激手段;慢邮就是基于当前的所见所感,对未来的自己或Ta人说的一些话,比如,此时此刻,你想呤诗一首,或者瞎YY,那又有何不可呢?假如你要写给未来的自己,那么未来的你看到这些话该作何感想呢?惊喜、激情、平淡、给力还是呵呵呢?引用一句歌词:
我不放弃,爱的勇气;我不怀疑,会有真心;我要握住一个最美的梦,给未来的自己!
定时任务:node-schedule
1、指定一个具体时间执行任务
var schedule = require('node-schedule');
var date = new Date(2016, 10, 11, 23, 59, 59);
//月份从0开始算
var j = schedule.scheduleJob(date, function(){
console.log('这不应该是个虐狗的时节!');
});
2、每天指定一个时间将到期的邮件发送
var registerTask=function(hour,minute,taskname){
return new Promise(function(resolve,reject){
var rule = new schedule.RecurrenceRule();
//每天这个时刻定时执行任务
rule.dayOfWeek = [0, new schedule.Range(1, 6)];
rule.hour = hour;
rule.minute = minute;
var j = schedule.scheduleJob(rule, function(){
console.log("开始发送:"+taskname);
resolve();
});
});
}
3、时间的设置取决于rule的配置
(1)、每秒:rule.second=[0,1,2,...59];
(2)、每分钟:rule.minute=[0,1,2,...59];
(3)、每小时:rule.hour=[0,1,2,...23];
(4)、每周几:rule.dayOfWeek=[0,1,...7];
(5)、每月几号:rule.dayOfMonth=[1,2,3,...31];
(6)、每月:rule.month=[1,2,...12];
4、到期重新赋值
var schedule = require('node-schedule');
var date = new Date(2016, 10, 11, 23, 59, 59);
var x = 'old value!';
var j = schedule.scheduleJob(date, function(y){
console.log(y);
}.bind(null,x));
x = 'new value';
不出意外的话,定时任务就可以跑起来了;
如果你也在使用pm2的话,想必会根据CPU的核数开启多个进程(比如:pm2 start ./app.js -i 4),那么恭喜你,你将碰到一个很有意思的问题:你的定时任务会重复4次发送同一个邮件;
听人说,定时任务最好独立出去单独运行,这个独立站点只执行定时任务,不使用pm2启动,想了想挺有道理的;好笑的是,我独立一个站点不开启多个进程依然会多次发送邮件;因为我使用的是mongoose,这个独立站点里require不到主站里的models,于是我在主站里新增了两个GET请求,发送邮件的站点定时去请求主站的待发送邮件的数据,发送完毕后回调里再请求去更新发送状态,最后的结果是仍然会重复发送;思来想去,然后我就此卡住了!
时间过去了大概不到一个月,突然有一天,我发现作为一个前端,要想学好Node,数据库才是最大的短板啊!再看了下mongodb,果然,不用mongoose,不require主站的models也能在这两个不同的站点访问同一个数据库;于是之前卡住的问题就迎刃而解了;————跳到邮件发送!
邮件发送:nodemailer
这个问题挺多的,但是稳住了就不会有什么问题了;一般就密码的问题,重复发送会被认为是垃圾邮件;以下为完整版,目前为止能顺利的用,倾情推荐:
var emailManage = {};
var nodemailer = require("nodemailer");
var smtpTransport = require('nodemailer-smtp-transport');
emailManage.send = function (_data,geter,title,htmlbody) {
return new Promise(function(resolve,reject){
var transport = nodemailer.createTransport(smtpTransport({
host: "smtp.qq.com", // 主机
port: 465, // SMTP 端口
auth: {
user: "915905174@qq.com", // 账号
pass: "去邮箱设置后获取,不是QQ密码"
}
}));
transport.sendMail({
from: "915905174@qq.com", // 发件地址
to: geter, // 收件列表
subject: title, // 标题
html: htmlbody
}, function(error, response) {
error&&reject(error);
resolve(_data);
//transport.close(); // 如果没用,关闭连接池
});
});
}
module.exports=emailManage;
跳回定时任务。独立出来的站点是可以连接到主站的数据库的,不用想着去require主站的models了;至此,慢邮版块的定时邮件发送任务就完成了;
var mongodb = require('mongodb');
var server = new mongodb.Server('localhost', 27017, {auto_reconnect:true});
var db = new mongodb.Db('dbname', server, {safe:true});
var dbColl=null;
var openDB=function(){
return new Promise(function(resolve,reject){
db.open(function(err,dab){
err&&reject(err);
resolve(dab);
});
});
}
var getCollection=function(db,coll){
return new Promise(function(resolve,reject){
db.collection(coll,{safe:true},function(err,collection){
err&&reject(err);
dbColl=collection;
resolve(collection);
});
});
}
var getFus=function(collection){
return new Promise(function(resolve,reject){
var dateDayStamp = new Date(new Date().getFullYear()+'-'+(new Date().getMonth()+1)+'-'+new Date().getDate()).getTime()+'';
collection.find({timeStamp:{$lte:dateDayStamp},sended:0}).toArray(function(err,fus){
err&&reject(err);
resolve(fus);
});
});
}
var fusPromises=function(fus){
if (fus.length) {
return fus.map(function(f){
return emailManage.send(
{
fid:f.fid,
getter:f.getter,
sender:f.sender,
emailto:f.emailto
},
f.emailto,
'你好,这是一封'+f.timeName+'前'+f.sender+'发给您的-时光慢递',
decodeURIComponent(f.body)
);
});
}
return [Promise.reject('need not to send ...')];
//直接跳到catch
}
var updateFus=function(ifs){
var updateOne=function(f){
return new Promise(function(resolve,reject){
dbColl.update({fid:f.fid},{$set:{sended:1}},{},function(err){
err&&reject(err);
console.log('sended to '+f.emailto);
console.log('+---------------------------------+');
resolve();
});
});
}
return ifs.map(function(f){
return updateOne(f);
});
}
registerTask(22,45,'慢邮')
.then(function(){
return openDB();
})
.then(function(dba){
return getCollection(dba,'futures');
})
.then(function(collection){
return getFus(collection);
})
.then(function(fus){
return Promise.all(fusPromises(fus));
})
.then(function(ifs){
return Promise.all(updateFus(ifs));
})
.then(function(){
console.log('all sended');
})
.catch(function(err){
console.log(err);
});
好了,先给Promise点个赞!
原文来自:花满楼(http://www.famanoder.com/bokes/57f6cb7c25beee9890c8985c);
热门评论
赞一个哈,讲的好好~
不错不错。。。。。。。。
require主站的models是什么意思啊?