【nodejs定时任务】Nodejs定时任务、邮件发送的详细介绍

时间:2020-11-19  来源:邮件  阅读:

定时任务:node-schedule

1、指定一个具体时间执行任务

 
1var schedule = require("node-schedule");
2var date = new Date(2016, 10, 11, 23, 59, 59);
3//月份从0开始算
4var j = schedule.scheduleJob(date, function(){
5  console.log("这不应该是个虐狗的时节!");
6});
 
2、每天指定一个时间将到期的邮件发送

 
1var registerTask=function(hour,minute,taskname){
2    return new Promise(function(resolve,reject){
3        var rule = new schedule.RecurrenceRule();
4        //每天这个时刻定时执行任务
5      rule.dayOfWeek = [0, new schedule.Range(1, 6)];
6      rule.hour = hour;
7      rule.minute = minute;
8      var j = schedule.scheduleJob(rule, function(){
9        console.log("开始发送:"+taskname);
10            resolve();
11      });
12    });
13}
 
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、到期重新赋值

 
1var schedule = require("node-schedule");
2var date = new Date(2016, 10, 11, 23, 59, 59);
3var x = "old value!";
4var j = schedule.scheduleJob(date, function(y){
5  console.log(y);
6}.bind(null,x));
7x = "new value";
 
不出意外的话,定时任务就可以跑起来了;

如果你也在使用pm2的话,想必会根据CPU的核数开启多个进程(比如:pm2 start ./app.js -i 4),那么恭喜你,你将碰到一个很有意思的问题:你的定时任务会重复4次发送同一个邮件;

听人说,定时任务最好独立出去单独运行,这个独立站点只执行定时任务,不使用pm2启动,想了想挺有道理的;好笑的是,我独立一个站点不开启多个进程依然会多次发送邮件;因为我使用的是mongoose,这个独立站点里require不到主站里的models,于是我在主站里新增了两个GET请求,发送邮件的站点定时去请求主站的待发送邮件的数据,发送完毕后回调里再请求去更新发送状态,最后的结果是仍然会重复发送;思来想去,然后我就此卡住了!

时间过去了大概不到一个月,突然有一天,我发现作为一个前端,要想学好Node,数据库才是最大的短板啊!再看了下mongodb,果然,不用mongoose,不require主站的models也能在这两个不同的站点访问同一个数据库;于是之前卡住的问题就迎刃而解了;————跳到邮件发送!

邮件发送:nodemailer

这个问题挺多的,但是稳住了就不会有什么问题了;一般就密码的问题,重复发送会被认为是垃圾邮件;以下为完整版,目前为止能顺利的用,倾情推荐:

 
1var emailManage = {};
2var nodemailer = require("nodemailer");
3var smtpTransport = require("nodemailer-smtp-transport");
4
5emailManage.send = function (_data,geter,title,htmlbody) {
6    return new Promise(function(resolve,reject){
7        var transport = nodemailer.createTransport(smtpTransport({
8            host: "smtp.qq.com", // 主机
9            port: 465, // SMTP 端口
10            auth: {
11                user: "915905174@qq.com", // 账号
12                pass: "去邮箱设置后获取,不是QQ密码"
13            }
14        }));
15        transport.sendMail({
16            from: "915905174@qq.com", // 发件地址
17            to: geter, // 收件列表
18            subject: title, // 标题
19            html: htmlbody
20        }, function(error, response) {
21            error&&reject(error);
22            resolve(_data);
23            //transport.close(); // 如果没用,关闭连接池
24        });
25    });
26}
27module.exports=emailManage;
 
跳回定时任务。独立出来的站点是可以连接到主站的数据库的,不用想着去require主站的models了;至此,慢邮版块的定时邮件发送任务就完成了;

 
1var  mongodb = require("mongodb");
2var  server  = new mongodb.Server("localhost", 27017, {auto_reconnect:true});
3var  db = new mongodb.Db("dbname", server, {safe:true});
4var dbColl=null;
5var openDB=function(){
6    return new Promise(function(resolve,reject){
7        db.open(function(err,dab){
8            err&&reject(err);
9            resolve(dab);
10        });
11    });
12}
13var getCollection=function(db,coll){
14    return new Promise(function(resolve,reject){
15        db.collection(coll,{safe:true},function(err,collection){
16            err&&reject(err);
17            dbColl=collection;
18            resolve(collection);
19        });
20    });
21}
22var getFus=function(collection){
23    return new Promise(function(resolve,reject){
24        var dateDayStamp = new Date(new Date().getFullYear()+"-"+(new Date().getMonth()+1)+"-"+new Date().getDate()).getTime()+"";
25        collection.find({timeStamp:{$lte:dateDayStamp},sended:0}).toArray(function(err,fus){
26            err&&reject(err);
27            resolve(fus);
28        });
29    });
30}
31var fusPromises=function(fus){
32    if (fus.length) {
33        return fus.map(function(f){
34            return emailManage.send(
35                {
36                    fid:f.fid,
37                    getter:f.getter,
38                    sender:f.sender,
39                    emailto:f.emailto
40                },
41                f.emailto,
42                "你好,这是一封"+f.timeName+"前"+f.sender+"发给您的-时光慢递",
43                decodeURIComponent(f.body)
44            );
45        });
46    }
47    return [Promise.reject("need not to send ...")];
48    //直接跳到catch
49}
50var updateFus=function(ifs){
51    var updateOne=function(f){
52        return new Promise(function(resolve,reject){
53            dbColl.update({fid:f.fid},{$set:{sended:1}},{},function(err){
54                err&&reject(err);
55                console.log("sended to "+f.emailto);
56                console.log("+---------------------------------+");
57                resolve();
58              });
59        });
60    }
61    return ifs.map(function(f){
62        return updateOne(f);
63    });
64}
65
66registerTask(22,45,"慢邮")
67.then(function(){
68    return openDB();
69})
70.then(function(dba){
71    return getCollection(dba,"futures");
72})
73.then(function(collection){
74    return getFus(collection);
75})
76.then(function(fus){
77    return Promise.all(fusPromises(fus));
78})
79.then(function(ifs){
80    return Promise.all(updateFus(ifs));
81})
82.then(function(){
83    console.log("all sended");
84})
85.catch(function(err){
86    console.log(err);
87});
 
好了,先给Promise点个赞!

【nodejs定时任务】Nodejs定时任务、邮件发送的详细介绍

http://m.bbyears.com/jsp/111389.html

推荐访问:
相关阅读 猜你喜欢
本类排行 本类最新