nodejs学习笔记5
来源:互联网 发布:java打字小游戏源代码 编辑:程序博客网 时间:2024/06/06 20:43
测试模块
选取node中的node-tap工具进行异步测试。
将node-tap包含进package.json文件的dev-dependencies就可安装它:
{ "name":"myApp", "version":"0.1.0", "devDependencies"{ "tap":"*" }}
然后执行命令:npm install
注:devDependencies属性是声明只用于开发和测试应用程序的依赖模块。
当在产品模式下安装应用程序时,可以使用-production选项跳过安装devDependencies所列的模块。
npm install -production
编写测试
一般来说创建一个tests目录放置测试脚本,且每个要测试的模块都包含一个文件。首先获得test构造函数:
var test = require('tap').test;//定义一个测试。传入测试名和一个包含测试代码的函数test("addtion of 2 and 2 works",function(t){ t.equal(2+2,4,"2+2 should be 4"); t.end();});
参数t包含面向测试的控制对象。利用该对象可以测试是否符合你的期望。并结束当前测试。
运行测试:node my_test.js.即可得到结果
使用断言测试模块
导入assert模块:
var assert = require('assert');var a = true;assert(a);//可以传入一个消息来在测试失败时提供更多的显示信息assert(a,"a should be truthy");//相当于js的“==”操作符assert.equal('10',10,'should be equal');//相当于js的“===”操作符assert.strictEqual('10',10,'string 10 should be equas to number 10');assert.notEqual('10',10,'should be equal');assert.notStrictEqual('10',10,'string 10 should be equas to number 10');
每一个断言函数都会设置一个期望条件,如果期望条件不满足则会抛出一个异常。
如果想测试两个对象,则这两个对象的引用必须指向同一个对象才会相等。
assert.equal({a:1},{a:1});//抛出异常
如果想比较对象的属性,就要用到深比较:
var obj = {b:1,a:[1,2,3]};assert.deepEqual(obj,{a:[1,2,3],b:1});//不会抛出异常
deepEqual函数验证的仅仅是对象的可枚举属性。如果两个对象具有不同的原型,但是他们的所有可枚举属性相同,他们就不会表现出不同。
使用node-tap中的内置断言函数
用它来代替Node核心模块中的断言函数可好处是:可以查看测试计数,错误报告,合计报告等。
test('truthyness of numbers',function(t){ //测试值是否为真 t.ok(1,'1 should be truthy'); //测试值是否为假 t.notOk(0,'0 should not be truthy'); t.end();});//t.equal函数测试严格相等性或浅相等性:test('sum works',function(t){ var a = 2=2; t.equal(a,'4','2+2 should be 4');//断言失效 t.notEqual(a,4,'2+2 should not be 4'); t.end();});//等价性测试test('object equivalency',function(t){ var a = {a:1,b:2}; t.equivalent(a,{b:2,a:1}); t.end();});//判断一个对象是否包含一系列属性test('object similarity',function(t){ var a = {a:1,b:2}; t.similar(a,{a:1}); t.end();});//测试对象类型test('object type',function(t){ t.type(1,"number"); t.end();})
控制回调流程
可以使用ASYNC控制库来控制回调流程。首先安装async模块:
npm install async.
下面实现一个给定数值平方的HTTP服务器。
var port = 8080;require('http').createServer(function(req,res){ var body = ""; req.setEncoding('utf8'); req.on('data',function(data){ body += data; }); req.once('end',function(){ var number = JSON.parse(body); var squared = Math.pow(number,2); res.end(JSON.stringify(squared)); });}).listen(port,function(){ console.log('squaring server listening on port 8080');});
串行执行
可以利用async.series函数将两个I/O操作串接起来。
var async = require('async'), request = require('request');function done(err,results){ if(err){throw err;} console.log('results:%j',results);}async.series({ function(next){ request.post({uri:'http://localhost:8080',body:'4'}, function(err,res,body){ next(err,body && JSON.parse(body)); } ); }, function(next){ request.post({uri:'http://localhost:8080',body:'5'}, function(err,res,body){ next(err,body && JSON.parse(body)); } ); }},done);
所有函数都结束后,会调用回调函数done,此时done函数带有每个回调函数的异步结果。以上执行后的结果为:results:[16,25].
并发执行
只要将上述例子的async.series改为async.parallel即可并发执行回调函数。
连续传递
如果下一个回调函数的执行取决于前一个回调函数结果。就可使用async.waterfall函数。
function done(err,res,body){ if(err){throw err;} console.log('3^4=%d',body);}async.waterfall([ function(next){ request.post({uri:'http://localhost:8080',body:'3'},next); }, function(res,body,next){ request.post({uri:'http://localhost:8080',body:body},next); }],done);
排队
控制在给定时刻同时存在的正在进行作业的最大数量就可使用async.queue函数。该函数创建一个队列,基于一个函数处理其中的元素。队列的客户端将作业和并发的最大数量传入这个函数,按照顺序执行每个作业。
function done(err,results){ if(err){throw err;} console.log('results:%j',results);};var maximumConcurrency = 5;function worker(task,callback){ request.post({uri:'http://localhost:8080',body:JSON.stringify(task)}, function(err,res,body){ callback(err,body && JSON.parse(body)); } );}var queue = async.queue(worker,maximumConcurrency);[1,2,3,4,5,6,7,8,9,10].forEach(function(i){ queue.push(i,function(err,result){ if(err){throw err;} console.log(i+'^2=%d',result); });});
队列被创建之后可以修改最大并发数:
queue.concurrency = 10;
当队列达到最大并发数时,可以将一个函数赋给队列的saturated属性来监听:
queue.saturated = function(){ console.log('queue is saturated');};//也可以监听empty事件queue.empty = function(){ console.log('queue is empty');};//当返回作业的最后一项作业时,队列会发射drain事件queue.drain = function(){ console.log('queue is drained, no more work');};
迭代
var results = {};function done(err){ if(err){throw err;} console.log('done!results:%j',results);}var collection = [1,2,3,4];function iterator(value,callback){ request.post({ uri:'http://localhost:8080', body:JSON.stringify(value) }, function(err,res,body){ if(err) return callback(err); results[value] = JSON.parse(body); callback(); });}async.forEach(collectino,iterator,done);
当在所有元素完成了异步迭代之后,就会调用最后一个函数,即done。
如果向同步迭代可以使用async.forEachSeries(collection,iterator,done)函数。
如果向在异步迭代时控制最大并发数,可以使用async.forEachLimit():
var maximumConcurrency = 5;async.forEachLimit(collection,maximumConcurrency,iterator,done);
映射
function done(err,results){ if(err){throw err;} console.log('done!results:%j',results);}var collection = [1,2,3,4];function iterator(value,callback){ request.post({ uri:'http://localhost:8080', body:JSON.stringify(value) }, function(err,res,body){ callback(err,body&&JSON.parse(body)); });}async.map(collection,iterator,done);
async.map()函数将每个结果传递给迭代函数中的回调函数,获得所有结果后按照正确的顺序将结果提交给done函数。
规约
与javascript的array.reduce()函数类似,不过他是异步执行的。
var collection = [1,2,3,4];function done(err,results){ if(err){throw err;} console.log('the sum of the squares of %j is %d',collection,results);}function iterator(memo,item,callback){ request.post({ uri:'http://localhost:8080', body:JSON.stringify(item) }, function(err,res,body){ callback(err,body&&(memo+JSON.parse(body))); });}//第二个参数为初始值。然后在集合上的每个集合迭代,当一次迭代结束时,就将一个新的memo值传入回调函数,再加上memo原来的值async.reduce(collection,0,iterator,done);
过滤
在js中可以对基于一个函数对集合进行过滤。async.filter可以异步执行相同的操作。
var collection = [1,2,3,4,5];function done(result){ console.log('these are the elements whose square value is greater than 10:%j',result);}function test(value){ return value>10;}function filter(item,callback){ request.post({ uri:'http://localhost:8080', body:JSON.stringify(item) }, function(err,res,body){ callback(body && test(JSON.parse(body))); });}async.filter(collection,filter,done);还有一个与filter作用相反的函数:async.reject(collection,filter,done);
检测
当满足某个条件时,想停止迭代。例如检测集合中第一个平方大于10的数。
var collection = [1,2,3,4,5];function done(result){ console.log('the firsr element whose square value is greater than 10:%j',result);}function test(value){ return value>10;}function detect(item,callback){ request.post({ uri:'http://localhost:8080', body:JSON.stringify(item) }, function(err,res,body){ callback(body && test(JSON.parse(body))); });}async.detect(collection,detect,done);//可以使用detect的串行版本async.detectSeries(collection,detect,done);
- nodejs学习笔记5
- nodejs 学习笔记--debug
- NodeJS学习笔记
- nodejs学习笔记
- nodeJs学习笔记
- nodejs学习笔记
- NodeJS 学习笔记1
- 学习nodejs笔记一
- 学习nodejs笔记二
- Nodejs Monog 学习笔记
- nodejs学习笔记一
- NodeJS学习笔记
- nodejs学习笔记
- nodejs学习笔记1
- nodejs学习笔记2
- NodeJS学习笔记
- nodejs 学习笔记
- Nodejs学习笔记
- Spring Session Redis集成(一)
- 谈谈程序猿的职业方向
- 装饰者模式
- 判断两个时间段是否重叠的算法
- Boost 常用的编译命令
- nodejs学习笔记5
- 获取当前机器的系统指标
- 新年新目标
- MySQL数据库的备份与恢复
- 使用拦截器Filter修补输入框的xss漏洞
- 数字图像学习 形态学运算
- Android textView二三事
- DICOM图像彩色问题RGBRGB或者RRGGBB
- CreeLinks物联网平台_处理器CeAd资源使用说明(使用CeAd采集电压)