Javascript OOP - 从对象方法中的函数返回值(嵌套函数)

时间:2012-08-02 14:18:30

标签: javascript oop

我遇到了从对象方法中的函数返回值的麻烦。我怎么能这样做?让我用代码解释一下。

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 个答案:

答案 0 :(得分: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分配。 (告诉我们您使用的是什么异步库)

您的示例中的其他代码气味

但你的代码也有其他气味。您的内部函数queryDBsuccesserror函数在闭包中定义,为了便于阅读,它们应该被定义为局部范围变量:

var success = function (data) {
    // process data
    return data;
}

答案 1 :(得分:1)

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

答案 2 :(得分: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);

答案 3 :(得分:1)

如果queryDB是异步的,那么对于queryDB来说,这是一个很好的建议(特别是如果你使用jQuery),因此getPerson(修改你的代码)返回一个" promise"类型对象。根据该承诺,您可以附加更多成功/失败/完成类型回调以继续处理。在jQuery中,这些回调孩子可以使用donefailalways来完成,如下所示:

   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或其他任何事情......他们只需要访问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
 })

等。这样你就不必在事件发生之前传递回调。很酷。