我如何 return 来自 `$http` 的数据与 $q 解析?
How can I return data from `$http` with a $q resolve?
我有一个 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;
});
谁能告诉我我可能做错了什么。我以为 resolve 也会 return 数据,但似乎没有这样做。
试试这个。
return topicService.getTopics("/" + subjectService.subject.id)
.then((data): void => {
// data seems to be not defined
var x = data;
} // ADDED
);
我认为是因为代码中缺少 },所以数据在 getTopics 函数中没有任何值。
试试这个语法,当我将一些现有的 $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(...)
本身就是一个可以被调用代码进一步使用的承诺。
也许这是个人喜好问题,但我使用 $q.defer()
技术来 "promisify" 一个同步函数。对于已经是异步的东西,即已经是一个承诺,比如 $http
和 $timeout
,我使用 then
函数设置一个成功处理程序,根据需要修改结果 return 使用 $q.when()
作为承诺的对象
参考when
函数中的$q documentation
我创建了一个 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);
});
我有一个 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;
});
谁能告诉我我可能做错了什么。我以为 resolve 也会 return 数据,但似乎没有这样做。
试试这个。
return topicService.getTopics("/" + subjectService.subject.id)
.then((data): void => {
// data seems to be not defined
var x = data;
} // ADDED
);
我认为是因为代码中缺少 },所以数据在 getTopics 函数中没有任何值。
试试这个语法,当我将一些现有的 $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(...)
本身就是一个可以被调用代码进一步使用的承诺。
也许这是个人喜好问题,但我使用 $q.defer()
技术来 "promisify" 一个同步函数。对于已经是异步的东西,即已经是一个承诺,比如 $http
和 $timeout
,我使用 then
函数设置一个成功处理程序,根据需要修改结果 return 使用 $q.when()
参考when
函数中的$q documentation
我创建了一个 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);
});