在 node.js 中使用 q 时如何删除样板代码
How to remove the boilerplate code when using q in node.js
我目前正在使用 q 和 Node.js
。我所有的模型都使用 q
的承诺。后来才知道这样写了一大堆样板代码
count: function(){
var deferred = Q.defer()
User.count(function(err,count){
if(err)
deferred.reject(err)
else
deferred.resolve(count)
})
return deferred.promise;
},
findAll: function(){
var deferred = Q.defer()
User.find({}, function(err,users){
if(err)
deferred.reject(err)
else
deferred.resolve(users)
})
return deferred.promise;
}
有没有办法删除这个样板代码?
注意: Q 具有以下内置版本,因此如果您正在使用 Q(如 OP 一样),请参阅 。如果您正在使用其他一些 promise 库,请查看是否可以;如果没有,请参阅下文。
您可以给自己一个实用函数来包装 Node 风格的调用并将它们转化为 promise(但请继续阅读),所以:
count: function() {
return makePromise(User.count)
}
makePromise
看起来像
function makePromise(f) {
var deferred = Q.defer()
var args = Array.prototype.slice.call(arguments)
args[0] = function(err) {
if(err)
deferred.reject(err)
else
deferred.resolve(Array.prototype.slice.call(arguments, 1))
}
f.apply(null, args)
return deferred.promise
}
(我正在尝试遵循您的惯例,即 ASI 将更正的 ;
)
它调用你给它的函数,传递任何进一步的参数,当它得到响应时要么使用 err
拒绝承诺,要么使用它在 [= 之后得到的参数数组解析它16=]。可以与所有以 err
作为第一个参数调用回调的 Node 风格函数一起使用。
但是,有人已经为您完成了:promisify
:-) 我很确定至少还有一个。
稍微复杂一点的版本将支持选择性地预先给出 thisArg
:
function makePromise(obj, f) {
var deferred = Q.defer()
var args, func, thisArg;
if (typeof obj === "function") {
thisArg = null
func = obj
args = Array.prototype.slice.call(arguments)
} else {
thisArg = obj
func = f
args = Array.prototype.slice.call(arguments, 1)
}
args[0] = function(err) {
if(err)
deferred.reject(err)
else
deferred.resolve(Array.prototype.slice.call(arguments, 1))
}
func.apply(thisArg, args)
return deferred.promise
}
那么如果User.count
需要用this
= User
调用:
count: function() {
return makePromise(User, User.count)
}
Is there a way remove this boilerplate code?
是的,Q 有 dedicated helper functions for interfacing with node callbacks。
您可以将代码简化为
count: function(){
return Q.nfcall(User.count);
},
findAll: function(){
return Q.nfcall(User.find, {});
}
如果这些方法依赖于它们的 this
值,您可以使用 Q.ninvoke(User, "count")
和 Q.ninvoke(User, "find", {})
。
您甚至可以使用 Q 的 function/method 绑定将其推向更高的极端并完全避免函数表达式:
count: Q.nfbind(User.count),
findAll: Q.nfbind(User.find, {})
或 this
值:
count: Q.nbind(User.count, User),
findAll: Q.nbind(User.find, User, {})
但是请注意,对于这些解决方案,您需要确保 count
和 findAll
以零参数调用。
我目前正在使用 q 和 Node.js
。我所有的模型都使用 q
的承诺。后来才知道这样写了一大堆样板代码
count: function(){
var deferred = Q.defer()
User.count(function(err,count){
if(err)
deferred.reject(err)
else
deferred.resolve(count)
})
return deferred.promise;
},
findAll: function(){
var deferred = Q.defer()
User.find({}, function(err,users){
if(err)
deferred.reject(err)
else
deferred.resolve(users)
})
return deferred.promise;
}
有没有办法删除这个样板代码?
注意: Q 具有以下内置版本,因此如果您正在使用 Q(如 OP 一样),请参阅
您可以给自己一个实用函数来包装 Node 风格的调用并将它们转化为 promise(但请继续阅读),所以:
count: function() {
return makePromise(User.count)
}
makePromise
看起来像
function makePromise(f) {
var deferred = Q.defer()
var args = Array.prototype.slice.call(arguments)
args[0] = function(err) {
if(err)
deferred.reject(err)
else
deferred.resolve(Array.prototype.slice.call(arguments, 1))
}
f.apply(null, args)
return deferred.promise
}
(我正在尝试遵循您的惯例,即 ASI 将更正的 ;
)
它调用你给它的函数,传递任何进一步的参数,当它得到响应时要么使用 err
拒绝承诺,要么使用它在 [= 之后得到的参数数组解析它16=]。可以与所有以 err
作为第一个参数调用回调的 Node 风格函数一起使用。
但是,有人已经为您完成了:promisify
:-) 我很确定至少还有一个。
稍微复杂一点的版本将支持选择性地预先给出 thisArg
:
function makePromise(obj, f) {
var deferred = Q.defer()
var args, func, thisArg;
if (typeof obj === "function") {
thisArg = null
func = obj
args = Array.prototype.slice.call(arguments)
} else {
thisArg = obj
func = f
args = Array.prototype.slice.call(arguments, 1)
}
args[0] = function(err) {
if(err)
deferred.reject(err)
else
deferred.resolve(Array.prototype.slice.call(arguments, 1))
}
func.apply(thisArg, args)
return deferred.promise
}
那么如果User.count
需要用this
= User
调用:
count: function() {
return makePromise(User, User.count)
}
Is there a way remove this boilerplate code?
是的,Q 有 dedicated helper functions for interfacing with node callbacks。
您可以将代码简化为
count: function(){
return Q.nfcall(User.count);
},
findAll: function(){
return Q.nfcall(User.find, {});
}
如果这些方法依赖于它们的 this
值,您可以使用 Q.ninvoke(User, "count")
和 Q.ninvoke(User, "find", {})
。
您甚至可以使用 Q 的 function/method 绑定将其推向更高的极端并完全避免函数表达式:
count: Q.nfbind(User.count),
findAll: Q.nfbind(User.find, {})
或 this
值:
count: Q.nbind(User.count, User),
findAll: Q.nbind(User.find, User, {})
但是请注意,对于这些解决方案,您需要确保 count
和 findAll
以零参数调用。