2015-08-26 2 views
0

Этот фрагмент является частью более крупной директивы:Почему загрузка не выполняется, и поэтому обещания не решены?

 var imageArray = []; 
     for (var i = 0; i < $scope.abbreviations.length; i++) { 
      imageArray[i] = new Image(); 
      imageArray[i].src = $scope.abbreviations[i].imgPath; 
     }; 
     console.log(imageArray); 

     function preLoad() { 

      var promises = []; 

      function loadImage(src) { 
       return $q(function (resolve, reject) { 
        var image = new Image(); 
        image.src = src; 
        image.onload = function() { 
         resolve(image); 
         console.log('onload:', src); 
        }; 
        image.onerror = function (e) { 
         reject(e); 
         console.log('onerror:', e); 
        }; 
       }) 
      } 
      imageArray.forEach(function (src) { 
       console.log('forEach:', src); 
       promises.push(loadImage(src)); 
      }); 

      return $q.all(promises).then(function (results) { 
       console.log('Promises resolved with', results); 
       $scope.results = results; 
      }); 
     } 
     preLoad().then(function() { 
      console.log('Ready for next activity...'); 
     }); 

и этот скриншот показывает журналы в моей консоли:

enter image description here

Вопрос: почему функция загрузки не удается, и, как следствие, обещания не решены?

+2

Похоже, журналы дают вам ключи. Это связано с тем, что ваши изображения загружаются с ошибкой в ​​событии с ошибкой, которые отвергают обещание, и вы только цепляетесь через «then» блок обещаний, возвращаемый q.all, цепляйте блок catch и видите. q.all обещание будет разрешено _ только, если все основные обещания будут разрешены. – PSL

+0

@PSL cheers Я вижу это. Почему загрузка происходит неудачно? спасибо –

+2

Это должен быть ваш вопрос правильно? то это не имеет ничего общего с обещаниями -> 'почему функции загрузки не работают и, как следствие, обетования не решены?'. – PSL

ответ

1

Проблема здесь:

imageArray.forEach(function(src) { 
    ... 
} 

Проходите в forEach обратного вызова элемент imageArray - но это уже объект изображения. Поэтому, когда вы назначаете его в src нового изображения, загрузка не выполняется.

Простейшее решение будет пропускать этот цикл в начале вашего кода и активировать обратный вызов forEach, чтобы он работал с исходным объектом. Фактически, чище использовать .map с возвратом результата:

promises = $scope.abbreviations.map(function(imgObj) { 
    return loadImage(imgObj.imgPath); 
}); 
+0

Полезное эмпирическое правило - если вы добавляете элемент в некоторый массив при каждом вызове обратного вызова 'forEach', вместо этого используйте вместо него' map'. Именно это я и сделал.) – raina77ow

+0

Это выглядит аккуратно, и он работает. Узнал две вещи, спасибо большое. –