node——含有异步函数的函数封装
在写代码时我们会发现有大量的重复代码,为了使代码更加简洁,我们可以将重复的代码封装为一个可以在多个部分时候用的函数。
之前写的新闻代码中,经常出现的操作有对文件的读取,我们可以将它封装为一个函数readNewsData()
function readNewsData(){
fs.readFile(path.join(__dirname,'data','data1.json'),'utf8',function(err,data){
if(err&&err.code!=='ENOENT'){
throw err;
} var list_news=JSON.parse(data||'[]');
//return list;//在这样返回值是不正确的,这里返回的值是fs.readfile返回的值,不是readNewsData函数返回的值 });
return list; }
在读取文件后返回list,但是因为有fs.readFile,fs.readFile有异步回调
当执行readNewsData函数时,先开启fs.readfile(),在开启后立即执行下面的return list;根本不会等fs.readfile将文件读完。
所以对于有异步回调的和函数,我们不能以return的形式返回值
所以:通过回调函数callback()将读取到的数据list,传递出去
function readNewsData(callback){
fs.readFile(path.join(__dirname,'data','data1.json'),'utf8',function(err,data){
if(err&&err.code!=='ENOENT'){
throw err;
} var list_news=JSON.parse(data||'[]');
//通过回调函数callback()将读取到的数据list,传递出去
callback(list_news);
});
}
在引用的时候:原代码
else if(urlObj.pathname==='/item'&&req.method==='get'){ fs.readFile(path.join(__dirname,'data','data1.json'),'utf8',function(err,data){ if(err&&err.code!=='ENOENT'){ throw err;
}
var model=null; var list_news=JSON.parse(data||'[]'); for(var i=0;i<list_news.length;i++)
{ if(list_news[i].id.toString()===urlObj.query.id)
{
model=list_news[i];
break; }
}
if(model)
{
res.render(path.join(__dirname,'views','details.html'),{item:model});
}
else
{
res.end('no found')
} });
现在:
else if(urlObj.pathname==='/item'&&req.method==='get'){ readNewsData(function(list){ for(var i=0;i<list.length;i++)
{ if(list[i].id.toString()===urlObj.query.id)
{
model=list[i];
break; }
}
if(model)
{
res.render(path.join(__dirname,'views','details.html'),{item:model});
}
else
{
res.end('no found')
}
}) }
这样代码会少一些,而readNewsData(function(list){});里面的list就是封装函数里面callback(list)
写入文件函数和上面的方法一样
原代码:
else if(req.url.startsWith('/add')&&req.method==='post'){
fs.readFile(path.join(__dirname,'data','data1.json'),'utf8',function(err,data){
//因为第一次访问网站,data1.json文件本身就不存在,所以会有异常
//这种错误,我们不认为是网站出错了,所以不需要抛出异常
if(err&&err.code!=='ENOENT'){
throw err;
}
//如果data没有读取到,则data为空,转换为数组
var list_news=JSON.parse(data||'[]'); var array=[];
req.on('data',function(chunk){
//此处的chunk参数,就是浏览器本次提交过来的一部分数据
//chunk的数据类型是buffer
array.push(chunk); }); //监听request对象的end事件
//当end事件被触发时,数据提交完成
req.on('end',function(){
var postBody=Buffer.concat(array);
postBody=postBody.toString('utf8'); postBody=querystring.parse(postBody); //把新闻添加到list之前,为新闻增加一个id
postBody.id=list_news.length; //将用户的push提交到新闻push到List_news中
list_news.push(postBody);
fs.writeFile(path.join(__dirname,'data','data1.json'),JSON.stringify(list_news),function(err){
if(err){
throw err;
}
console.log('ok');
}); res.statusCode=302;//跳转
res.statusMessage='Found';
res.setHeader('Location','/');
res.end('over');
}); }); }
红色部分封装代码
//封装一个写入data1.json的函数
//这里传过来的data是转换为字符串的数据
function writeNewsData(data,callback){
fs.writeFile(path.join(__dirname,'data','data1.json'),data,function(err){
if(err){
throw err;
}
console.log('ok');
}); //这里写当写入数据完毕后的操作
callback();
}
修改后:
else if(req.url.startsWith('/add')&&req.method==='post'){
readNewsData(function(list_news){
var array=[];
req.on('data',function(chunk){
array.push(chunk); }); req.on('end',function(){
var postBody=Buffer.concat(array);
postBody=postBody.toString('utf8'); postBody=querystring.parse(postBody); postBody.id=list_news.length;
list_news.push(postBody);
writeNewsData(JSON.stringify(list_news),function(){
res.statusCode=302;
res.statusMessage='Found';
res.setHeader('Location','/');
res.end('over'); }); }); }); }
上面post提交数据还可以封装为一个函数
function postBodyData(req,callback){ var array=[];
req.on('data',function(chunk){
array.push(chunk); }); req.on('end',function(){
var postBody=Buffer.concat(array);
postBody=postBody.toString('utf8'); postBody=querystring.parse(postBody);
//把用户post提交过来的返回
callback(postBody);
});
}
原来post函数修改后
else if(req.url.startsWith('/add')&&req.method==='post'){
//1.读取data1.json
readNewsData(function(list_news){
//2.读取用户post提交的数据
postBodyData(req,function(postBody){
//3.为用户提交的新闻增加一个id属性,并且把新闻对象push到list中
postBody.id=list_news.length;
list_news.push(postBody);
//将list数组写入到data1.json中
writeNewsData(JSON.stringify(list_news),function(){
res.statusCode=;
res.statusMessage='Found';
res.setHeader('Location','/');
res.end('over'); });
});
}); }
这样原来有20多行的代码,就精简到了十多行,并且封装的函数可以在很多地方使用。
node——含有异步函数的函数封装的更多相关文章
- 转: ES6异步编程:Generator 函数的含义与用法
转: ES6异步编程:Generator 函数的含义与用法 异步编程对 JavaScript 语言太重要.JavaScript 只有一根线程,如果没有异步编程,根本没法用,非卡死不可. 以前,异步编程 ...
- node基础06:回调函数
1.Node异步编程 Node.js 异步编程的直接体现就是回调. 异步编程依托于回调来实现,但不能说使用了回调后程序就异步化了. 回调函数在完成任务后就会被调用,Node 使用了大量的回调函数,No ...
- 转: ES6异步编程:Thunk函数的含义与用法
转: ES6异步编程:Thunk函数的含义与用法 参数的求值策略 Thunk函数早在上个世纪60年代就诞生了. 那时,编程语言刚刚起步,计算机学家还在研究,编译器怎么写比较好.一个争论的焦点是&quo ...
- C#中 多线程执行含有返回值的函数
C# 中,传统的多线程并不支持多线程执行含有返回结果的函数.虽然可以通过制作外壳类来使得返回结果得以保留,但如果一定时间内函数未执行完,简单的外壳类可能就无法满足需求了. class netHelpe ...
- 转: ES6异步编程: co函数库的含义与用法
转: ES6异步编程: co函数库的含义与用法 co 函数库是著名程序员 TJ Holowaychuk 于2013年6月发布的一个小工具,用于 Generator 函数的自动执行. 比如,有一个 Ge ...
- 6.26学习 异步委托回调函数 VS 多线程 VS 并行处理
描述: 我现在是轮询着构建实例,然后这个实例去执行一个方法,但是执行方法需要大约10s时间,全部轮询下来需要很长时间.所以我现在要更改,头给了我两个方法,1多线程 2异步委托回调函数. 异步委托回调函 ...
- Thinkphp3.2.3框架下封装公共的函数,例如封装CURL函数来获取接口数据
当我们需要在控制层调用相同的封装函数时,写多次相同的函数,显得代码十分的拉杂,不精简: TP框架有一个很好的机制,可以再Common定义一个function.php函数,当我们在控制层调用的时候直接调 ...
- AsyncTask函数化的封装,AsyncTask函数式的调用
AsyncTask在本专栏已经做过详细的解析,但是AsyncTask函数式的调用这个概念对大多数人来说比较陌生.其实本质就是自己封装AsyncTask,让暴露的方法,看不到一点AsyncTask的身影 ...
- js对函数参数的封装
对函数参数的封装 一个原始函数有n个参数,用wrap对函数进行封装,生成一个新的函数,当给它传入参数数量为n的时候,将执行原始函数,否则不执行 //函数封装 function wrap(func){ ...
随机推荐
- jsmind实现思维导图,和echars 的tree图类似
https://blog.csdn.net/qq_41619796/article/details/88552029
- JQ淡入淡出效果
<script type="text/javascript"> //页面淡入淡出 $(document).ready(function() { $('body').hi ...
- 51nod1072 - 威佐夫游戏【威佐夫博弈】
有2堆石子.A B两个人轮流拿,A先拿.每次可以从一堆中取任意个或从2堆中取相同数量的石子,但不可不取.拿到最后1颗石子的人获胜.假设A B都非常聪明,拿石子的过程中不会出现失误.给出2堆石子的数量, ...
- mysql 每个月创建新表
1.CREATE DEFINER=`root`@`%` PROCEDURE `aa`()BEGIN SET @sqlstr = CONCAT('create table cdrpbx10_',DATE ...
- CENTOS 7发送邮件测试
centos7作为126邮箱客户端发送邮件测试. 首先安装客户端软件: yum install sendmail mailx -y 配置邮箱设置: 开启smtp发件协议 配置授权码,写入配置文件. 追 ...
- 模拟ArrayList底层实现
package chengbaoDemo; import java.util.ArrayList; import java.util.Arrays; import comman.Human; /** ...
- nodejs-Sream
Stream 是一个抽象接口,Node 中有很多对象实现了这个接口.例如,对http 服务器发起请求的request 对象就是一个 Stream,还有stdout(标准输出). Node.js,Str ...
- [HTML 5] Atomic Relevant Busy
Together 'aria-live', we can use 'aria-atomic', 'aria-relevant' and 'aria-busy' to give more informa ...
- Android測试APP工具(一)
近期面试APP开发者的时候,遇到了技术总监问 APP測试的概念性问题.后面感觉主要的项目流程.项目逻辑.屏幕适配. 測试是全然没有问题的.可是对于APP的性能測试.压力測试等高端的測试.还是存在着美中 ...
- hive join 优化 --小表join大表
1.小.大表 join 在小表和大表进行join时,将小表放在前边,效率会高.hive会将小表进行缓存. 2.mapjoin 使用mapjoin将小表放入内存,在map端和大表逐一匹配.从而省去red ...