从对象方法内部的函数返回值时遇到问题。我怎么能这么做?让我用代码解释一下。
function ObjPerson() {
this.getPerson = function() {
function queryDB() {
//run query and pass result data to success or error functions
}
function success(data) {
//process data
return data;
}
function error(errorData) {
//process error
}
queryDB();
}
}
var person = new ObjPerson;
var userData = ObjPerson.getPerson();
问题是getPerson()方法没有返回任何内容。最好的方法是什么?
谢谢!
如果这是一个同步函数,则返回值
function ObjPerson() {
this.getPerson = function() {
function queryDB() {
//run query and pass result data to success or error functions
}
function success(data) {
//process data
return data;
}
function error(errorData) {
//process error
}
return queryDB(); // HERE'S THE CHANGE
}
}
var person = new ObjPerson(); // always use parentheses
var userData = person.getPerson(); // ERROR: getPerson is instance function
但是,如果这个函数是异步的,那么您应该以不同的方式执行它。不幸的是,你不能只打电话给:
var userData = person.getPerson();
因为在进行分配时,您的异步调用可能还没有返回。。。因此,您的userData
分配应该在异步调用之后分配。(告诉我们你在使用什么异步库)
示例中的其他代码气味
但您的代码也有其他气味。您的内部函数queryDB
、success
和error
函数是在闭包中定义的,为了可读性,它们应该定义为局部范围变量:
var success = function (data) {
// process data
return data;
}
函数getPerson不返回任何值,您应该使用return
来分配值(注意return data
为function success
返回值)
我从未使用过phonegap,但基于它的文档:
当调用SQLTransaction的executeSql方法时,它将使用SQLResultSet调用它的回调。
您可能使用的executeSql是异步的。这意味着,例如,你必须更改它,而不是:
var person = new ObjPerson;
var userData = ObjPerson.getPerson();
// something here using userData
你必须:
function ObjPerson() {
this.getPerson = function(requestSuccesfullCallback) {
function queryDB() {
//run query and pass result data to success or error functions
}
function success(data) {
//process data
requestSuccesfullCallback(data);
}
function error(errorData) {
//process error
}
queryDB();
}
}
function callback(userData)
{
// something here using userData
}
var person = new ObjPerson;
ObjPerson.getPerson(callback);
如果queryDB是异步的,那么queryDB和getPerson(在修改代码的情况下)返回一个"promise"类型的对象是一个很好的建议(尤其是当您使用jQuery时)。根据该承诺,您可以附加更多成功/失败/已完成类型的回调以继续处理。在jQuery中,这些回调的子代可以用done
、fail
、always
来完成,如下所示:
var person = new ObjPerson;
var userDataPromise = ObjPerson.getPerson();
userDataPromise.done(function(person){
//deal with person object here
//
}).fail(function(errorobj){
//deal with error
}).always(function(){
//deal with completion
});
现在,如果使用jQuery库,可以返回ajax调用中返回的promise。这不是我的建议。很可能,您对如何调用person
有一些严格的要求。此外,您真的不想让代码的其他部分知道您在做ajax或localDB或任何事情。。。他们只需要访问CCD_ 12。
因此,这里有一个关于如何完成代码的粗略草图。
function ObjPerson() {
function getData (args,success,fail){
//somehow get your data. We'll assume it doesn't return promises
}
this.getPersonPromise = function() {
var returnedPromise = $.Deferred();
getData(args,function(data){
//success callback
//process data (assume PersonCustomData is defined elsewhere)
var person = new PersonCustomData (data)
returnedPromise.resolve(person);
}, function(error) {
//failure callback, return custom errors, or maybe
//just return original error if lazy or don't quite know all methods
//of failure or something.
var errorObj = ...
returnedPromise.reject(errorObj);
});
return returnedPromise;
}
}
var person = new ObjPerson;
var promise = ObjPerson.getPersonPromise();
person.done(function(person){
//do more stuff with PersonCustomData instance
}).fail(function(errorObj){
//oops
})
等等。这样,你就不必在事后再进行回调。非常酷。