代码地址https://github.com/MoceptWeb/...阅读前请确保你至少已经看懂了egg文档,否则看下面是浪费时间。如有不对之处,请猛烈提醒。egg定时任务有很多,我们需要每隔一段时间(或者只执行一次)执行某些脚本。这时候我们就可以使用egg的schedule功能了。schedule的写法{app_root}/app/schedule.js//使用schedule属性设置定时任务的执行间隔等配置staticgetschedule(){return{interval:'5m',//5分钟间隔类型:'worker',//worker类型:每台机器上只有一个worker会执行这个定时任务};}asyncsubscribe(){this.ctx.logger.info('scheduleupdateOa2Userbegin')constres=awaitthis.ctx.service.portal.oa.updateOa2User();this.ctx.logger.info('scheduleupdateOa2Userfinish')}self判断启动哪些定时任务在getschedule()中配置immediate:当这个参数配置为true时,这个定时任务会在应用启动后立即执行一次并且准备好了oa.jssqlserver连接//helper.js连接到一个sqlserver连接constmssql=require('mssql')letpool=awaitmssql.connect(config)//app.js连接错误日志mssql.on('error',err=>{console.log('databaseerr',err)app.logger.error(err);//...错误处理器})异步中都是异步完成的多个操作,比如对一条数据逐条执行异步操作,但最后要得到所有的异步结果,不要在异步中做同步操作,否则执行顺序很意外!!!asyncupdateUser(oaUser){constself=this;让promiseAll=[];//设置promise对象并同步发送请求oaUser.forEach(oa=>{promiseAll.push(Promise.resolve(self.updateUserByName(oa)));});等待Promise.all(promiseAll);}{app_root}/app/service/portal/portal.jsasynchronousmultipleoperationsasynchronouscompleted如果需要一步步获取所有数据(这里是同步的)执行其他所有的异步操作,需要将同步操作封装成支持异步操作的承诺。//专门逐行处理文件,获取所有数据并返回(promise)asyncreadLine(target){letarray=[];常量自我=这个;constfile=awaitnewPromise(function(resolve,reject){lineReader.eachLine(target,function(line,last){//line.split(/\s/)[0]letdata=line.split(/\s/)if(data[2]){array.push({user_id:self.ctx.helper.trim(data[0],'"'),mail:self.ctx.helper.trim(data[1],'"'),user_center_id:self.ctx.helper.trim(data[2],'"'),})}if(last){resolve(array)}})})returnfile;}//使用constfileData=awaitthis.readLine(target);letpromiseAll=[];fileData.forEach(portal=>{promiseAll.push(Promise.resolve(self.updateUserByPortalId(portal)));});awaitPromise.all(promiseAll);mysqlsql的占位符constres=awaitconn.query('updatet_usersetmail=?whereuser_id=?',[oaUser.email,user.user_id]);sql的事务asyncsqlBeginTransaction(){constconn=awaitthis.app.mysql.beginTransaction();try{constres=awaitconn.query('updatet_usersetmail=?whereuser_id=?',[oaUser.email,user.user_id]);if(res&&res.affectedRows===1){awaitconn.commit();}elseif(res.affectedRows>1){//this.ctx.logger.error('')awaitconn.rollback()}else{awaitconn.rollback()}}catch(err){//错误,回滚等待conn.rollback();//回滚调用不会抛出错误throwerr;}}extend{app_root}/app/extend/helper.js统一封装各种数据连接和错误信息test{app_root}/app/test/service/portal/portal.test.js待完成单元测试描述config牢记每个环境使用的配置不一样单元测试使用config.unittest.jsroutecontrolroute和control一起使用,可以使用postman直接调试为什么要这样写TODO?分析源码扩展优化将服务中的纯数据库封装到模型中基于redis优化任务消息队列不需要手动开启任务编写egg-mssql连接sqlserver
