#angularjs #closures #promise
#angularjs #замыкания #обещание
Вопрос:
Мне нужна ваша помощь, чтобы решить эту проблему, на самом деле, я не понимаю, как получить результат обещания в каком-то вложенном обещании, ниже приведен мой код
// service
mainApp.factory('myService', ['CmisManager', '$q', 'ServiceCMIS', function(CmisManager, $q, ServiceCMIS) {
get_detailFold: function(_objectId){
return ServiceCMIS.getDocumentProperties(_objectId)
.then(function(data){
var items = [] ;
var imgListe = data.succinctProperties['tsi:image_liste'].split(';') ;
(function(imgListe){
for (var i=0; i<imgListe.length; i ) {
(function(index){
var item = {} ;
item.id = imgListe[index] ;
return ServiceCMIS.getDocumentProperties(imgListe[index])
.then(function(data){
var contentStreamId = data.succinctProperties['cmis:contentStreamId'] ;
return ServiceCMIS.getContentStreamDocumentURL(data[index], contentStreamId)
.then(function(data){
item.urlThumbnail = data ;
item.urlDetail = data ;
items.push(item) ;
})
})
})(i) ;
}
return items ;
})(imgListe) ;
})
.then(null, function(error){
return error;
}) ;
}
};
}])
}])
// controleur
myService.get_detailFold(41946).then(function(data){
$scope.datatest = data ;
}) ;
Я ожидал получить такой результат
[
{"id":1, "urlThumbnail":"./img/test/1.jpg", "urlDetail":"./img/test/1.jpg"},
{"id":2, "urlThumbnail":"./img/test/2.jpg", "urlDetail":"./img/test/2.jpg"},
{"id":3, "urlThumbnail":"./img/test/3.jpg", "urlDetail":"./img/test/3.jpg"},
{"id":4, "urlThumbnail":"./img/test/4.jpg", "urlDetail":"./img/test/4.jpg"},
{"id":5, "urlThumbnail":"./img/test/5.jpg", "urlDetail":"./img/test/5.jpg"}
]
но вместо этого я получил неопределенный
Заранее спасибо за вашу помощь
Комментарии:
1. для информации, в режиме отладки я правильно получаю необходимое значение в переменной item.
Ответ №1:
Вы должны действительно использовать .map
.forEach
циклы и, чтобы избежать этих неприятных замыканий вокруг ваших циклов.
Тем не менее, ваша проблема довольно проста, вы возвращаетесь изнутри этого замыкания, а не снаружи.
return items ;
})(imgListe) ;
Возвращает из анонимной вызываемой функции для закрытия, вместо этого для начала выполните:
})(imgListe) ;
return items ;
Тем не менее, вы все еще не заполняете элементы в правильном порядке, поскольку он не будет ждать их всех — для этого используйте $q.all
, который ожидает массив обещаний. Ваш код должен выглядеть примерно так:
mainApp.factory('myService', ['CmisManager', '$q', 'ServiceCMIS', function(CmisManager, $q, ServiceCMIS) {
//...
get_detailFold: function(_objectId){
return ServiceCMIS.getDocumentProperties(_objectId).then(function(data){
var items = [] ;
var imgList = data.succinctProperties['tsi:image_liste'].split(';');
var ps = imgListe.map(function(img){
return ServiceCMIS.getDocumentProperties(img).then(function(properties){
var contentStreamId = data.succinctProperties['cmis:contentStreamId'];
return ServiceCMIS.getContentStreamDocumentURL(img, contentStreamId);
}).then(function(data){
return { id:img, urlThumbnail: data, urlDetail: data };
});
});
return $q.all(ps); // waits for all promises to resolve
}); // don't .catch here, let the other side handle failures
}
}]);