1

我无法从对象方法内的函数返回值。我怎么能这样做?让我用代码解释一下。

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() 方法没有返回任何内容。最好的方法是什么?

谢谢!

4

4 回答 4

4

如果这是一个同步函数,则返回该值

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和函数是在闭包中定义的successerror为了便于阅读,它们应该定义为局部范围变量:

var success = function (data) {
    // process data
    return data;
}
于 2012-08-02T14:23:27.540 回答
1

函数 getPerson 不返回任何内容,您应该使用return它来分配一个值(请注意,return data返回一个值function success

于 2012-08-02T14:23:09.160 回答
1

我从未使用过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);
于 2012-08-02T14:38:50.647 回答
1

如果 queryDB 是异步的,那么对于 queryDB 和 getPerson(修改您的代码)返回“promise”类型对象是一个很好的建议(尤其是如果您使用 jQuery)。从该承诺中,您可以附加更多成功/失败/已完成类型的回调以继续处理。在 jQuery 中,那些回调函数可以用done,来完成failalways如下所示:

   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 调用中返回的承诺。那不是我要建议的。person很可能,您对如何调用您有一些严格的要求。此外,您真的不在乎让代码的其他部分知道您正在执行 ajax 或 localDB 或其他任何东西......他们只需要访问person.

所以这里有一个关于如何完成代码来做到这一点的粗略草图。

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
 })

等等。这样你就不必在事后传递回调。很酷。

于 2012-08-02T15:02:21.997 回答