Angular JS (1.2.26) 在 forEach 循环中承诺

Angular JS (1.2.26) promises in a forEach loop

我有一个 angular.forEach 循环遍历图像配置对象,以便根据配置中的 URL 创建 javascript Image() 对象。

不希望返回生成的图像,直到所有图像都正确加载。如何通过使用 Angular promises?

实现此目的

考虑以下(简化的)代码片段:

function getImages(imageConfigurations) {
    var images = [];

    angular.forEach(imageConfigurations, function (config) {
        var imageObject = loadImageFromUrl(config.url);

        var imageData = {
            name: config.name,
            order: config.order,
            image: imageObject
        };

        images.push(imageData);

    });

    //Do not return this untill all of the image objects from forEach loop 
    //have fired their 'onload' event
    return images;

}

function loadImageFromUrl(url) {
    var imageObj = new Image();

    imageObj.onload = function () {
        //Resolve promise?
    };

    imageObj.src = url;
} 

下面需要你注入$q服务...

您可以做的第一件事是将图像加载包装在一个承诺中,例如

function loadImageFromUrl(url) {
    return $q(function(resolve) { // ignoring error conditions for now
        var imageObj = new Image();

        imageObj.onload = function () {
            resolve(imageObj);
        };

        imageObj.src = url;
    });        
}

然后,您可以使用$q.all等待所有的承诺解决

function getImages(imageConfigurations) {
    // map imageConfigurations to an array of promises
    var promises = imageConfigurations.map(function(config) {
        return loadImageFromUrl(config.url).then(function(imageObj) {
            // chain the loadImageFromUrl promise to create the
            // imageData object and return it to resolve the promise
            return {
                name: config.name,
                order: config.order,
                image: imageObj
            };
        });
    });

    return $q.all(promises);
}

当该承诺解决时,您将拥有一个 imageData 对象数组

getImages(configs).then(function(imageDataArray) {
    // tada!
});

这是 Angular 1.2.x 需要的 loadImageFromUrl 版本。参见 https://code.angularjs.org/1.2.26/docs/api/ng/service/$q

function loadImageFromUrl(url) {
    var deferred = $q.defer(),
        imageObj = new Image();

    imageObj.onload = function () {
        deferred.resolve(imageObj);
    };
    imageObj.src = url;

    return deferred.promise;
}

注意 getImages 现在是异步的 -

  function getImages(imageConfigurations) {
     var deferred = $q.defer();
     var images = [];
     var imagePromises = imageConfigurations.map(function (config) {
         var imagePromise = loadImageFromUrl(config.url);
         return imagePromise;
     });

     return $q.all(imagePromises).then(function(images){
          return images.map(function(imageObject){
             // create image object 
           })
        });
 }  

从 url 加载图像现在也是异步的 -

   function loadImageFromUrl(url) {
         var defer = $q.defer();
         var imageObj = new Image();

         imageObj.onload = function () {
            defer.resolve("image has been loaded - yay");
         };

         imageObj.src = url;

         return defer.promise;
     }

$q 文档到这里 - https://docs.angularjs.org/api/ng/service/$q

祝你好运