利用promise写出更加优美的nodejs程序
2016-03-12 12:23
701 查看
利用promise写出更加优美的nodejs程序
时间 2014-04-28 10:42:17 sundaqing的个人空间
原文 http://my.oschina.net/sundq/blog/227410
主题 Node.js
什么是 promise
promise 一个标准,它描述了异步调用的返回结果,包括正确返回结果和错误处理。关于详细的说明文档可以参考 Promises/A+ 。目前实现 promise 标准的模块有很多,如 Q 、 bluebird 和 Deferred ,下面我们以 Q 为例,介绍一下 promise 在 nodejs 中的使用方法。
将一般的异步调用的函数转换为 promise 风格的函数
比如一般情况下,我们异步读取文件会写出下面的代码:
fs.readFile(“test.txt”,function(err,data){
if(!err){
console.log(data);
}else{
console.error(err);
}
});
我们可以把 fs.readFile 函数封装为 promise 风格的函数,如下:
var preadFile = function(file){
fs.readFile(file,function(err,data){
var deferred = Q.defer();
if(!err){
deferred.resolve(data);
}else{
deferred.reject(err);
}
});
}
这样我们就可以这样调用这个方法了:
//then 的第一个参数是正确处理函数,第二个参数是错误处理函数
preadFile(“test.txt”).then(console.log,console.error);
可以看到这样调用更加直接明了。
使用方法
各个回调函数顺序传递数据:
在 nodejs 中我们回去数据时,时常遇回调函数的返回结果需要传递给下一个回调函数,到时很大的回调函数嵌套, promise
可以很轻松的在回调函数之间传递参数,看下面的例子:
var fun1 = function (data,cb) {
cb(null,data+” fun1”);
}
var fun2 = function (data,cb) {
cb(null,data+” fun2”);
}
var fun3 = function (data,cb) {
cb(null,data+” fun3”);
}
function main(data,cb){
fun1(data,function(err,data){
if(!err){
fun2(data,function(err,data){
if(!err){
fun3(data,cb);
}else{
cb(err);
}
});
}else{
cb(err);
}
});
}
可以看到 main 函数为了得到数据,需要嵌套调用 fun1 , fun2 和 fun3 ,如果需要调用很多函数,那么会形成很大的回调函数嵌套调用,导致代码看起来很丑陋,而且不容易维护,下面我们改用 promise 重写这段代码:
var Q = require(“q”);
var fun1 = function (data) {
var deferred = Q.defer();
deferred.resolve(data+” fun1”);
return deferred.promise;
}
var fun2 = function (data) {
var deferred = Q.defer();
deferred.resolve(data+” fun2”);
return deferred.promise;
}
var fun3 = function (data) {
var deferred = Q.defer();
deferred.resolve(data+” fun3”);
return deferred.promise;
}
function main(data,cb){
fun2(“test”)
.then(fun3)
.then(fun4)
.done(function(data){
cb(null,data);//ok 获得的最终数据为 —>”test fun1 fun2 fun3”
},function(err){
cb(err);//failed
});
}
收集各个回调函数产生的数据:有时候我们需要执行很多回调函数,然手把这个回调函数的数据一齐传递给一个函数处理,此时我们可以使用 all 和 spread 方法,参看如下代码:
var Q = require(“q”);
var fun1 = function (data) {
var deferred = Q.defer();
deferred.resolve(data+” fun1”);
return deferred.promise;
}
var fun2 = function (data) {
var deferred = Q.defer();
deferred.resolve(data+” fun2”);
return deferred.promise;
}
var fun3 = function (data) {
var deferred = Q.defer();
deferred.resolve(data+” fun3”);
return deferred.promise;
}
Q.all([
fun2(“test1”),fun3(“test2”),fun4(“test3”)
]).spread(function(){
console.log(arguments);//获得的参数为(‘test1 fun1’, ‘test2 fun2’, ‘test3 fun3’ )
});
统一处理错误:传统的回调函数方式使用的话,我们需要在每一个回调函数里判断是否有错误需要处理,这样会存在很多冗余代码,使用 promise 的话,可以使用 done 或者 fail 统一在一个函数中处理错误,如第一个例子一样,使用 done 方法的第二个参数处理错误。
时间 2014-04-28 10:42:17 sundaqing的个人空间
原文 http://my.oschina.net/sundq/blog/227410
主题 Node.js
什么是 promise
promise 一个标准,它描述了异步调用的返回结果,包括正确返回结果和错误处理。关于详细的说明文档可以参考 Promises/A+ 。目前实现 promise 标准的模块有很多,如 Q 、 bluebird 和 Deferred ,下面我们以 Q 为例,介绍一下 promise 在 nodejs 中的使用方法。
将一般的异步调用的函数转换为 promise 风格的函数
比如一般情况下,我们异步读取文件会写出下面的代码:
fs.readFile(“test.txt”,function(err,data){
if(!err){
console.log(data);
}else{
console.error(err);
}
});
我们可以把 fs.readFile 函数封装为 promise 风格的函数,如下:
var preadFile = function(file){
fs.readFile(file,function(err,data){
var deferred = Q.defer();
if(!err){
deferred.resolve(data);
}else{
deferred.reject(err);
}
return deferred.promise;
});
}
这样我们就可以这样调用这个方法了:
//then 的第一个参数是正确处理函数,第二个参数是错误处理函数
preadFile(“test.txt”).then(console.log,console.error);
可以看到这样调用更加直接明了。
使用方法
各个回调函数顺序传递数据:
在 nodejs 中我们回去数据时,时常遇回调函数的返回结果需要传递给下一个回调函数,到时很大的回调函数嵌套, promise
可以很轻松的在回调函数之间传递参数,看下面的例子:
var fun1 = function (data,cb) {
cb(null,data+” fun1”);
}
var fun2 = function (data,cb) {
cb(null,data+” fun2”);
}
var fun3 = function (data,cb) {
cb(null,data+” fun3”);
}
function main(data,cb){
fun1(data,function(err,data){
if(!err){
fun2(data,function(err,data){
if(!err){
fun3(data,cb);
}else{
cb(err);
}
});
}else{
cb(err);
}
});
}
可以看到 main 函数为了得到数据,需要嵌套调用 fun1 , fun2 和 fun3 ,如果需要调用很多函数,那么会形成很大的回调函数嵌套调用,导致代码看起来很丑陋,而且不容易维护,下面我们改用 promise 重写这段代码:
var Q = require(“q”);
var fun1 = function (data) {
var deferred = Q.defer();
deferred.resolve(data+” fun1”);
return deferred.promise;
}
var fun2 = function (data) {
var deferred = Q.defer();
deferred.resolve(data+” fun2”);
return deferred.promise;
}
var fun3 = function (data) {
var deferred = Q.defer();
deferred.resolve(data+” fun3”);
return deferred.promise;
}
function main(data,cb){
fun2(“test”)
.then(fun3)
.then(fun4)
.done(function(data){
cb(null,data);//ok 获得的最终数据为 —>”test fun1 fun2 fun3”
},function(err){
cb(err);//failed
});
}
收集各个回调函数产生的数据:有时候我们需要执行很多回调函数,然手把这个回调函数的数据一齐传递给一个函数处理,此时我们可以使用 all 和 spread 方法,参看如下代码:
var Q = require(“q”);
var fun1 = function (data) {
var deferred = Q.defer();
deferred.resolve(data+” fun1”);
return deferred.promise;
}
var fun2 = function (data) {
var deferred = Q.defer();
deferred.resolve(data+” fun2”);
return deferred.promise;
}
var fun3 = function (data) {
var deferred = Q.defer();
deferred.resolve(data+” fun3”);
return deferred.promise;
}
Q.all([
fun2(“test1”),fun3(“test2”),fun4(“test3”)
]).spread(function(){
console.log(arguments);//获得的参数为(‘test1 fun1’, ‘test2 fun2’, ‘test3 fun3’ )
});
统一处理错误:传统的回调函数方式使用的话,我们需要在每一个回调函数里判断是否有错误需要处理,这样会存在很多冗余代码,使用 promise 的话,可以使用 done 或者 fail 统一在一个函数中处理错误,如第一个例子一样,使用 done 方法的第二个参数处理错误。
相关文章推荐
- Node.js中Process.nextTick()和setImmediate()的区别
- node浅析-npm自带
- [nodejs] nodejs开发个人博客(五)分配数据
- Node.js的Express框架使用上手指南
- Node.js编写爬虫的基本思路及抓取百度图片的实例分享
- 深入浅出Node.js(二):Node.js&NPM的安装与配置
- 安装node多版本管理器nvm,以及nvm常用命令
- Node.js中setTimeout和setInterval的使用
- parentNode、parentElement,childNodes、children 它们有什么区别呢?
- DOM parentNode
- DOM children childNodes nodetype
- Node.js全局对象
- Node.js项目中调用JavaScript的EJS模板库的方法
- Node.js最新技术栈之Promise篇
- java poi excel node
- NodeJS学习笔记
- nodejs+express一个很经典的问题--异步获取数据模板渲染
- NodeJS写日志_Log4js使用详解+常见艰难的解决
- 使用Mocha进行Node.js的单元测试
- 玩转Nodejs日志管理log4js