node.js下when.js 的异步编程实践
假设一个业务场景:
通过rss地址,获取rss并保存于文件,rss地址保存于文件中。
完成该场景的业务需要完成3个任务:
1.从文件中读取rss地址。
2.获取rss。
3.保存于文件。
最后将这三个任务进行整合。
准备:
存放rss地址的文件,address.txt。
http://programmer.csdn.net/rss_programmer.html
任务1:
读取rss地址文件的内容并通过callback返回。
vargetRssAddress=function(path,callback){ fs.readFile(path,{encoding:'utf8'},function(err,data){ callback(err,data); }); }
任务2:
通过rss地址get到rss,并通过callback返回错误或数据。
vargetRss=function(url,callback){ vardata=''; http.get(url,function(res){ res.on('data',function(chrunk){ data+=chrunk; }); res.on('end',function(){ callback(null,data); }); }).on('error',function(err){ callback(err,null); }); }
任务3:
将rss保存于文件并通过callback返回错误。
varsaveRss=function(data,callback){ fs.writeFile('rss.txt',data,'utf8',function(err){ callback(err); }); }
整合:
getRssAddress('address.txt',function(err,data){ if(err){ console.log(err); return; } getRss(data,function(err,data){ if(err){ console.log(err); return; } saveRss(data,function(err){ if(err)console.log(err); }); }); });
上面的代码是全异步处理,使用最常见的callback处理异步逻辑的返回,好处是标准写法,大家都能容易接受;坏处是耦合性太强,处理异常麻烦,代码不直观,特别是处理业务逻辑复杂和处理任务多的场景,层层的callback会让人眼冒金星,代码难以维护。
Promise/A规范的实现之一when.js正是针对这样的问题域。
让我们来看一下改造后的代码。
任务1:
vargetRssAddress=function(path){ vardeferred=when.defer(); fs.readFile(path,{encoding:'utf8'},function(err,data){ if(err)deferred.reject(err); deferred.resolve(data); });
returndeferred.promise; }