AngularJS工厂返回'undefined'

时间:2016-02-04 21:54:01

标签: angularjs

当我定义像这样的工厂方法时

dataFactory.all = function() {
  return 'test01';
}

并在控制器中调用它

console.log(Data.all());

我可以打印test01。但是,当我在工厂all()方法中添加一些逻辑时,就像这样

  dataFactory.all = function() {

    $http
      .get('/api/hey')
      .success(function(data) {

        $http
          .get('/api/hi')
          .success(function(data) {

            return 'test'; // 'test' can not be printed, and console show 'undefined'
          });
      });
     //return 'test01'; //can be printed;
  };

然后无法通过控制器打印'test'。因为我将return语句放在回调中?

请让我知道我做错了什么?

感谢。

5 个答案:

答案 0 :(得分:1)

您正在代码中进行一些异步调用,请访问此问题以获取更多详细信息和信息How do I return the response from an asynchronous call?

答案 1 :(得分:1)

是的,正如您所指出的那样,您将回报放在回调函数中。 all()函数没有return语句,默认情况下所有函数都将返回undefined

您遇到的问题是您现在正在处理将在未来未知时间返回数据的异步函数(而不是同步函数,它会立即返回数据以供下一行代码。)

在这种情况下,您使用$ http方法,$http.get()将返回一个承诺。 https://docs.angularjs.org/api/ng/service/ $ Q

查看$ http文档中的示例。具体来说,看看他们使用then()函数执行的操作:https://docs.angularjs.org/api/ng/service/ $ http

答案 2 :(得分:1)

我不认为它是因为你错误地构建了它,但看起来你的工厂($http)方法是异步运行的。尝试返回这样的承诺:

datafactory.all = function() {

   return new Promise(resolve, reject){
       // Your logic here...

     $http
        .get('/api/hey')
        .success(function(data) {
            resolve(data);
        })
        .fail(function(err){
           reject(err);
        });
     }

};

然后您可以像这样使用工厂方法:

datafactory.all().then(function(result){
   // Success!
}, function(err){
   // Error!
});

答案 3 :(得分:1)

看一下棱角分明的$qdocs)。使用$ q,您可以创建一个延迟对象,并从工厂方法返回它的承诺。

这应该允许您在then回调中从$ http调用中检索结果数据,因为您的工厂将返回一个承诺:

dataFactory.all = function() {
  // create deferred object
  var deferred = $q.defer();

  $http.get('/api/hey')
  .success(function(data) {

    $http.get('/api/hi') 
    .success(function(data) {

      // resolve the promise with your http request result, this value will 
      // be the result passed to  your factory method's 
      // `then` callback
      deferred.resolve(data);
    }
  }

  return deferred.promise;
}

<强>更新

@HankScorpio是对的,通过返回$http.get函数调用可以大大简化这一点,因为它们会自己返回promise:

dataFactory.all = function() {
  return $http.get('/api/hey').success(function(response) {
    return $http.get('/api/hi');
  });
}

工作更新在此处:http://plnkr.co/edit/wtMnOjjUnKV5x8CQrbIm?p=preview

答案 4 :(得分:1)

因为您没有在all方法的范围内返回任何值,所以您需要注意$http返回promise

所以..你的方法可能是这样的:

dataFactory.all = function(jobname) {
  return $http.get('/api/jobs/' + jobname + '/realtimeData').success(function(realtime) {
    return $http.get('/api/jobs/' + jobname + '/nonliveData').success(function(nonlive) {
      return 'test';
    });
  });
};

或者..来取消嵌套的承诺,你可以使用Flattened Promise Chains重构你的代码:

dataFactory.all = function(jobname) {
  return $http.get('/api/jobs/' + jobname + '/realtimeData').then(function(realtime) {
    // do something with realtime
    return $http.get('/api/jobs/' + jobname + '/nonliveData');
  }).then(function(nonlive){
    return 'test';
  });
};

因为您的方法all现在返回一个承诺,您需要:

dataFactory.all(jobname).then(function(nonlive){
  console.log(nonlive); // should return test!
});