Проблемы с вложенностью обещаний AngularJS

#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
    }
}]);