【问题标题】:How can I return data from `$http` with a $q resolve?如何通过 $q 解析从 `$http` 返回数据?
【发布时间】:2015-11-06 00:12:53
【问题描述】:

我有一个 javascript 函数,对于这个问题我已经简化了。它实际上对从 $http 调用中检索到的数据做了一些事情,然后我希望这些数据与调用它的函数的承诺一起可用:

getTopics = (queryString: string) => {
        var self = this;
        var defer = self.$q.defer();
        self.$http({
            // cache: true,
            url: self.ac.dataServer + '/api/Topic/GetMapData' + queryString,
            method: "GET"
        })
            .success((data) => {

                var output: ITopics = {
                    details: data
                }
                // output is correctly populated with data
                defer.resolve(output);

                // I also tried this and it get seen in the calling function either
                // defer.resolve('abc');
            })
        return defer.promise;
    };

这样称呼它:

return topicService.getTopics("/" + subjectService.subject.id)
       .then((data) => {
           // data seems to be not defined
           var x = data;
});

谁能告诉我我可能做错了什么。我认为解析也会返回数据,但似乎没有这样做。

【问题讨论】:

  • 您确定正在调用success 吗?也尝试删除: void
  • 是的,它在调试器中的 var x = data 处停止。但是当我将鼠标悬停在数据上时,chrome 调试器不显示任何内容。
  • 看起来您正在使用打字稿,但您将 data 结果声明为 void 而不是例如any。我不确定,但 void 听起来没有真正的内容
  • 我删除了 : void 还是一样。它转到 var x = data 但数据什么也没显示。如果我检查另一点并查看输出,它会正确填充数据
  • 可能是因为您忘记了 topicService 中 '{' 的结束标记。尝试在 var x = data 之后添加 '}';

标签: javascript angularjs typescript angular-promise angular-http


【解决方案1】:

试试这个。

return topicService.getTopics("/" + subjectService.subject.id)
   .then((data): void => {
       // data seems to be not defined
       var x = data;
   } // ADDED
);

我认为是因为代码中缺少 },这就是数据在 getTopics 函数中没有任何值的原因。

【讨论】:

  • 很抱歉,这只是我输入问题时的一个错误。 } 实际上在我的代码中。
【解决方案2】:

试试这个语法,当我将一些现有的$q 代码移动到 ES6 时,我改用了这个语法

getTopics(queryString) {
    return this.$q((resolve, reject) => {
        this.$http.get(self.ac.dataServer + '/api/Topic/GetMapData' + queryString)
        .success((data) => {
            resolve({details: data});
        })
        .error( (err) => reject(err) );
    });
}

或者更好,正如 Bergi 所建议的:

getTopics(queryString) {
    return this.$http.get(self.ac.dataServer + '/api/Topic/GetMapData' + queryString)
        .then( data => ({details: data}) );
    });
}

$http.get().then(...) 本身就是一个可以被调用代码进一步使用的承诺。

【讨论】:

  • 哈!感谢您的提示 - 我已经更改了自己的代码,但不确定 Anne 现在应该如何更改她的代码
  • 在这种情况下,它只是getTopics(…) { return $http.get(…).then(data => ({details:data})); }。您能帮助我们改进链接问题的答案吗?其中哪些部分难以理解?
  • 谢谢 - 希望我的解释正确
  • 对象字面量周围的括号在箭头函数中非常重要:-)
【解决方案3】:

也许这是个人喜好问题,但我使用$q.defer() 技术来“承诺”一个同步函数。如果某些东西已经是异步的,即已经是一个承诺,比如$http$timeout,我使用then 函数设置一个成功处理程序,根据需要修改结果并使用@987654327 作为承诺返回对象@

参考$q documentation中的when函数

我创建了一个 Plnkr(在 Javascript 中)来演示 $q.when 在这种情况下的使用。相关代码:

$scope.results = ['a', 'b', 'c', 'd'];
$scope.getTopics = function() {

  //Replace $timeout with $http
  // $http({
  // }).then....

  return $timeout(function() {
      console.log('Simulating HTTP response');
      return $scope.results;
    }, 1500)
    .then(function(res) {
      var updatedRes = [];
      //Modify the HTTP/timeout results
      console.log('Modifying HTTP/timeout result');
      angular.forEach(res, function(item) {
        item = item + '1';
        updatedRes.push(item);
      });

      //Wrap the result object in $q.when to create a promise
      return $q.when(updatedRes);
    });
};

$scope.getTopics().then(function(data) {
  console.log('Using the modified result');
  $scope.updatedResults = data;
  console.log('getTopics result = ', data);
});

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-02-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-08
    • 1970-01-01
    • 2012-12-07
    相关资源
    最近更新 更多