做了个Node项目,某个流程中最多五层回调进行逻辑判断,客户还要加一些业务,如果再这么做下去,至少还要加两层回调。就可读性来讲,是很差的。胃有点翻腾,要吐出来了…
在网上查了查,有很多人说Node的回调是个坑,但是个人还是愿意接受这不是Node坑的理论,回调这是Node的一个思想,我们既然选择了使用Node,就应该去分析、理解和适应它。
我相信无论遇到什么问题,总是能解决的。如果现在不能解决,那只是暂时没有想到解决办法而已。
一、generator(生成器)
是ES6标准引入的新的数据类型。一个generator看上去像一个函数,但可以返回多次。
我喜欢并在使用着这种方法,这种方法很优雅。
作用:一是同步流程控制Node回调;二是或以在外层获取回调函数内的返回值;三是如果逻辑判断层级很多,那么使代码的可读性更好;
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
//方法如下 function sync(gen){ var genObj = gen(resume); function resume() { genObj.next(arguments); } genObj.next(); } //文件读取实例 app.get('/fsdemo', function (req, res) { "use strict"; var fs = require('fs'), run = sync; run(function *gen(callback) { let ret = yield fs.readFile('C:\\Users\\Administrator\\Desktop\\备忘.txt', 'utf-8',callback); res.json(ret); }); }); //database操作如下 app.post('/loginAction',function(req,res){ var conn = require('../../connection')(app), crypto = require('crypto'), md5 = crypto.createHash('md5'), run = sync, data = req.body; md5.update(data.password); var username = data.username, password = md5.digest('hex'); var sql = 'select * from' + ' t_user where ' + 'username =\''+username+'\' ' + 'and password = \''+password+'\''; run(function * gen(callback){ var ret = yield conn.query(sql,callback); if(ret[0]){ console.log(ret[0]); console.log('你特么弄错了!!'); }else{ console.log(ret[1]); if(ret[1].length == 0){ console.log('用户名或者密码输入错误!'); }else{ console.log('登录成功!'); req.session.user = ret[1][0]; // res.json({'msg':'登录成功啦'}); //res.render('admin/dashboard',{user:req.session.user}); res.redirect('/dashboard'); } } }); }); |
二、async模块
需要安装 $ npm instanll async
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
async = require("async"); a = function (callback) { // 延迟5s模拟耗时操作 setTimeout(function () { console.log("hello world a"); // 回调给下一个函数 callback(null, "function a"); }, 5000); }; b = function (callback) { // 延迟1s模拟耗时操作 setTimeout(function () { console.log("hello world b"); // 回调给下一个函数 callback(null, "function b"); }, 1000); }; c = function (callback) { console.log("hello world c"); // 回调给下一个函数 callback(null, "function c"); }; // 根据b, a, c这样的顺序执行 async.series([b, a, c], function (error, result) { console.log(result); }); |
0 1 2 3 4 |
// 输出 hello world b hello world a hello world c [ 'function b', 'function a', 'function c' ] |
三、events模块
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
// 引入 events 模块 var events = require('events'); // 创建 eventEmitter 对象 var eventEmitter = new events.EventEmitter(); // 创建事件处理程序 var connectHandler = function connected() { console.log('连接成功。'); // 触发 data_received 事件 eventEmitter.emit('data_received'); } // 绑定 connection 事件处理程序 eventEmitter.on('connection', connectHandler); // 使用匿名函数绑定 data_received 事件 eventEmitter.on('data_received', function(){ console.log('数据接收成功。'); }); // 触发 connection 事件 eventEmitter.emit('connection'); console.log("程序执行完毕。"); // 输出 : // 连接成功 // 数据接收成功 // 程序执行完毕 |
相关文章: