Javascript 如何将Angular JS函数写入返回值
问题陈述:我有一个angular js函数从服务中获取数据,我连接了一些列,然后返回连接的数据 角度JS函数:Javascript 如何将Angular JS函数写入返回值,javascript,angularjs,Javascript,Angularjs,问题陈述:我有一个angular js函数从服务中获取数据,我连接了一些列,然后返回连接的数据 角度JS函数: $scope.findCompanyAddressById = function( cmpId ) { var address = ""; $http.get(someUrl+'/company/find?id='+cmpId ). then(function(response) { $scope.company = response.dat
$scope.findCompanyAddressById = function( cmpId ) {
var address = "";
$http.get(someUrl+'/company/find?id='+cmpId ).
then(function(response) {
$scope.company = response.data;
for( var i=0; i < $scope.company.locations.length; i++ ) {
address += " " + $scope.company.locations[i].street1
address += " " + $scope.company.locations[i].street2
address += " " + $scope.company.locations[i].city
address += " " + $scope.company.locations[i].state
address += " " + $scope.company.locations[i].zip
console.log( "Rendering address: " );
console.log( address ); // logs perfect data.
}
});
return address;
}
关于如何从上述函数返回连接数据的任何想法。这是一个异步数据。您不知道它何时到达(200毫秒后或一分钟后),因此无法将其分配给变量。您需要使用承诺异步回调 您的服务应如下所示:
$scope.concatenatedData = $scope.findCompanyAddressById( 1 );
$scope.findCompanyAddressById = function(cmpId) {
return $http.get(someUrl + '/company/find?id=' + cmpId).
then(function(response) {
var address = "";
$scope.company = response.data;
for (var i = 0; i < $scope.company.locations.length; i++) {
address += " " + $scope.company.locations[i].street1
address += " " + $scope.company.locations[i].street2
address += " " + $scope.company.locations[i].city
address += " " + $scope.company.locations[i].state
address += " " + $scope.company.locations[i].zip
}
return address;
});
}
$scope.findCompanyAddressById( 1 )
.then(function(address){
$scope.concatenatedData = address;
})
或者您可以将其传递给控制器(函数($scope,YourService)
),并执行相同的操作:
YourService.findCompanyAddressById( 1 ).then(...)
要帮助解决这个问题,您必须首先了解一点。承诺是异步的,因此不能保证立即返回。把承诺想象成“嘿,我保证我会为你做一些工作,然后当我完成后,我会把结果还给你”。这通常用于对服务器的HTTP调用 异步代码最酷的一点是,它允许您在执行异步代码时执行其他一些工作。这正是你在上面经历的事情 请注意,您的
回信地址
在功能之外。要实际查看异步特性的作用,请在return
语句之前放置一个控制台.log
,然后在中放置另一个。您将看到console.log在实际执行返回之前是第一个
也就是说,您将无法像以前使用的其他代码那样使用异步代码。一旦进入承诺,你真的无法“逃避”它。从现在开始,您需要继续遵守承诺来处理数据
$scope.findCompanyAddress(1).then(address => {
/* do something with address */
})
希望这有帮助
编辑
忘了还提到,这意味着您现在需要从函数返回承诺,而不是从地址返回承诺($http.get
部分)。$http.get是异步的,返回一个承诺,然后使用处理该承诺。因此,在解析承诺之前返回变量地址
有很多方法可以解决这个问题,但这就是我的方法:
$scope.findCompanyAddressById = function( cmpId ) {
return $http.get(
someUrl+'/company/find?id='+cmpId ).
then(function(response) {
var address = '';
$scope.company = response.data;
for( var i=0; i < $scope.company.locations.length; i++ ) {
address += " " + $scope.company.locations[i].street1
address += " " + $scope.company.locations[i].street2
address += " " + $scope.company.locations[i].city
address += " " + $scope.company.locations[i].state
address += " " + $scope.company.locations[i].zip
console.log( "Rendering address: " );
console.log( address ); // logs perfect data.
}
return address;
})
};
以下是有关的MDN文档
编辑
返回新承诺是一种反模式,因此函数现在从$http.get返回承诺。我认为您的模式是错误的。该函数在启动REST调用时立即返回;它不会等待它完成。在匿名函数中,您应该使用数据,而不是返回值。您应该将公司信息的REST API包装到一个角度资源中。请参阅例如@Tim Biegeleisen函数中的返回变量,在get响应体外部为空。它是否真的返回未定义的?或者这个空字符串:address=”“
?围绕已经返回承诺的函数创建新承诺的可能重复是一个众所周知的承诺反模式。谢谢它工作了,但是我想要这样的东西,我能不能喜欢它var address=$scope.findCompanyAddress(companyId)@您可以在服务中创建一个全局变量,但如果在控制器中使用,则会造成内存泄漏。所以你必须使用承诺:.then((data)=>{address=data;})
@AlekseySolovey地址在外面可用吗?@BadshahTracker否,它将在调用$http
之前使用,并且将始终显示未定义请告诉我任何方法,通过这些方法我可以在另一个变量中获取返回值并在其他地方使用它$scope.variable=$scope.findCompanyAddressById(1);考虑使用存储在ng模型等其他地方的$scope.variable,然后从那里获取它。可能的
$scope.findCompanyAddressById( 1 )
.then(function(address){
$scope.concatenatedData = address;
})