在 angular 中返回链式承诺的 "last" 值
Returning "last" value of chained promises in angular
我正在尝试进行一些地理定位,并根据坐标调用 RESTful API return 一些数据。然后我要解析这个数据,最后return就可以了
我对 angular.js 和承诺还很陌生,因此这段代码是我在互联网上看到的东西的混合体:D
我已经完成了所有工作,但我错过了最后一步:return将处理后的结果数组 ("allSpots") 发送给原始调用者。我在这里错过了什么?
.factory('wifiSpotFactory', function (WifinderModel, $q, $http) {
function onGeolocationSuccess(position) {
var url = 'http://localhost:34915/api/spots?latitude=' + position.coords.longitude + '&longitude=' + position.coords.latitude;
$http.get(url).then(function (response) {
var allSpots = [], data = response.data;
for (var i = 0; i < data.length; i++) {
var newSpot = new WifinderModel.wifiSpot(data[i].id, data[i].name, data[i].password, data[i].address);
allSpots.push(newSpot);
}
return allSpots;
}, function (error) {
console.log(error);
});
};
var wifiSpotFactory = {
loadNearSpots: function() {
var geo_options = {
enableHighAccuracy: true,
maximumAge: 50000,
timeout: 30000
};
var deferred = $q.defer();
navigator.geolocation.getCurrentPosition(deferred.resolve, deferred.reject, geo_options);
return deferred.promise
.then(onGeolocationSuccess)
.then(function(allSpots) { return allSpots; });
}
};
return wifiSpotFactory;
} )
那么在controller中,如何获取promise的值呢?
.controller('wifiListController', [
'$scope', 'wifiSpotFactory', function ($scope, wifiSpotFactory) {
$scope.spots = wifiSpotFactory.loadNearSpots();
}
])
Return 链接的承诺:
function onGeolocationSuccess(position) {
var url = 'http://localhost:34915/api/spots?latitude=' + position.coords.longitude + '&longitude=' + position.coords.latitude;
return $http.get(url).success(function(data, status, headers, config) {
var allSpots = [];
for (var i = 0; i < data.length; i++) {
var newSpot = new WifinderModel.wifiSpot(data[i].id, data[i].name, data[i].password, data[i].address);
allSpots.push(newSpot);
}
return allSpots;
}).error(function(data, status, headers, config) {});
};
那么调用可以是:
deferred.promise
.then(onGeolocationSuccess)
.then(function(allSpots) { ... });
Callback
没有 return 数据的能力,你真的应该在那里使用 promise 模式,它能够 return 来自 promise 的数据。您 onGeolocationSuccess
正在使用看似 return data
但实际上并非如此的回调模式。
你可以通过returnonGeolocationSuccess
方法的承诺来解决这个问题,为此你需要return$http.get
对象,它已经returns 是一个 promise 对象。在该函数的 .then
中,您将得到 data
,它从 API 编辑了 return。从 .then 函数你可以 return 一个 data
这将帮助你遵循 promise pattern.
代码
.factory('wifiSpotFactory', function(WifinderModel, $q, $http) {
function onGeolocationSuccess(position) {
var url = 'http://localhost:34915/api/spots?latitude=' + position.coords.longitude + '&longitude=' + position.coords.latitude;
return $http.get(url).
then(function(response) {
var allSpots = [],
data = response.data;
for (var i = 0; i < data.length; i++) {
var newSpot = new WifinderModel.wifiSpot(data[i].id, data[i].name, data[i].password, data[i].address);
allSpots.push(newSpot);
}
return allSpots;
}, function(error) {
console.log(error)
});
};
var wifiSpotFactory = {
loadNearSpots: function() {
//..other code as is..to make solution cleaner removed that part.
//return promise to follow promise chain
return deferred.promise
.then(onGeolocationSuccess)
.then(function(allSpots) {
return allSpots;
});
}
};
return wifiSpotFactory;
})
控制器
.controller('wifiListController', ['$scope', 'wifiSpotFactory',
function ($scope, wifiSpotFactory) {
wifiSpotFactory.loadNearSpots().then(function(data){
$scope.spots = data; //data will be available inside `.then` which promise resolve/reject
});
}
])
我正在尝试进行一些地理定位,并根据坐标调用 RESTful API return 一些数据。然后我要解析这个数据,最后return就可以了 我对 angular.js 和承诺还很陌生,因此这段代码是我在互联网上看到的东西的混合体:D
我已经完成了所有工作,但我错过了最后一步:return将处理后的结果数组 ("allSpots") 发送给原始调用者。我在这里错过了什么?
.factory('wifiSpotFactory', function (WifinderModel, $q, $http) {
function onGeolocationSuccess(position) {
var url = 'http://localhost:34915/api/spots?latitude=' + position.coords.longitude + '&longitude=' + position.coords.latitude;
$http.get(url).then(function (response) {
var allSpots = [], data = response.data;
for (var i = 0; i < data.length; i++) {
var newSpot = new WifinderModel.wifiSpot(data[i].id, data[i].name, data[i].password, data[i].address);
allSpots.push(newSpot);
}
return allSpots;
}, function (error) {
console.log(error);
});
};
var wifiSpotFactory = {
loadNearSpots: function() {
var geo_options = {
enableHighAccuracy: true,
maximumAge: 50000,
timeout: 30000
};
var deferred = $q.defer();
navigator.geolocation.getCurrentPosition(deferred.resolve, deferred.reject, geo_options);
return deferred.promise
.then(onGeolocationSuccess)
.then(function(allSpots) { return allSpots; });
}
};
return wifiSpotFactory;
} )
那么在controller中,如何获取promise的值呢?
.controller('wifiListController', [
'$scope', 'wifiSpotFactory', function ($scope, wifiSpotFactory) {
$scope.spots = wifiSpotFactory.loadNearSpots();
}
])
Return 链接的承诺:
function onGeolocationSuccess(position) {
var url = 'http://localhost:34915/api/spots?latitude=' + position.coords.longitude + '&longitude=' + position.coords.latitude;
return $http.get(url).success(function(data, status, headers, config) {
var allSpots = [];
for (var i = 0; i < data.length; i++) {
var newSpot = new WifinderModel.wifiSpot(data[i].id, data[i].name, data[i].password, data[i].address);
allSpots.push(newSpot);
}
return allSpots;
}).error(function(data, status, headers, config) {});
};
那么调用可以是:
deferred.promise
.then(onGeolocationSuccess)
.then(function(allSpots) { ... });
Callback
没有 return 数据的能力,你真的应该在那里使用 promise 模式,它能够 return 来自 promise 的数据。您 onGeolocationSuccess
正在使用看似 return data
但实际上并非如此的回调模式。
你可以通过returnonGeolocationSuccess
方法的承诺来解决这个问题,为此你需要return$http.get
对象,它已经returns 是一个 promise 对象。在该函数的 .then
中,您将得到 data
,它从 API 编辑了 return。从 .then 函数你可以 return 一个 data
这将帮助你遵循 promise pattern.
代码
.factory('wifiSpotFactory', function(WifinderModel, $q, $http) {
function onGeolocationSuccess(position) {
var url = 'http://localhost:34915/api/spots?latitude=' + position.coords.longitude + '&longitude=' + position.coords.latitude;
return $http.get(url).
then(function(response) {
var allSpots = [],
data = response.data;
for (var i = 0; i < data.length; i++) {
var newSpot = new WifinderModel.wifiSpot(data[i].id, data[i].name, data[i].password, data[i].address);
allSpots.push(newSpot);
}
return allSpots;
}, function(error) {
console.log(error)
});
};
var wifiSpotFactory = {
loadNearSpots: function() {
//..other code as is..to make solution cleaner removed that part.
//return promise to follow promise chain
return deferred.promise
.then(onGeolocationSuccess)
.then(function(allSpots) {
return allSpots;
});
}
};
return wifiSpotFactory;
})
控制器
.controller('wifiListController', ['$scope', 'wifiSpotFactory',
function ($scope, wifiSpotFactory) {
wifiSpotFactory.loadNearSpots().then(function(data){
$scope.spots = data; //data will be available inside `.then` which promise resolve/reject
});
}
])