假设一个业务场景:
通过rss地址,获取rss并保存于文件,rss地址保存于文件中。
完成该场景的业务需要完成3个任务:
1.从文件中读取rss地址。
2.获取rss。
3.保存于文件。
最后将这三个任务进行整合。
准备:
存放rss地址的文件,address.txt。
http://programmer.csdn.net/rss_programmer.html
任务1:
读取rss地址文件的内容并通过callback返回。
var getRssAddress = function(path, callback) {
fs.readFile(path, {encoding: \'utf8\'}, function (err, data) {
callback(err, data);
});
}
任务2:
通过rss地址get到rss,并通过callback返回错误或数据。
var getRss = function(url, callback) {
var data = \'\';
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返回错误。
var saveRss = 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:
var getRssAddress = function(path) {
var deferred = when.defer();
fs.readFile(path, {encoding: \'utf8\'}, function (err, data) {
if (err) deferred.reject(err);
deferred.resolve(data);
});
return deferred.promise;
}