Моя цель состоит в том, чтобы взять массив URL-адресов изображений (полученных из API, их заголовки CORS установлены) и перебрать его, извлечь каждое изображение с помощью xhr, изменив его размер элемент холста, а затем сгенерировать еще один массив, чьи записи являются данными для измененных изображений. Моя проблема в том, что только последняя запись в массиве обрабатывается должным образом, а все остальное - пустым изображением. Я предполагаю, что $ q.deferred() перезаписывается на каждой итерации цикла, но я действительно не знаю, потому что я новичок в обещаниях и асинхронных действиях. Кроме того, я пишу это в AngularJS v1.25. Вы можете просмотреть мой код по адресу http://codepen.io/anon/pen/razwyZ?editors=101. Я также разместим его здесь:
var myApp = angular.module('myApp', []);
//myApp.directive('myDirective', function() {});
//myApp.factory('myService', function() {});
myApp.controller('MyCtrl', ['$scope', '$q',
function($scope, $q) {
resizeImage = function(imgSrc) {
var deferred = $q.defer();
// console.log(imgSrc);
// console.log("resizing image");
image = new Image();
image.src = imgSrc;
image.onload = function() {
var canvas = document.createElement("canvas");
canvas.height = 300;
canvas.width = 300;
var ctx = canvas.getContext("2d");
ctx.drawImage(image, 0, 0, 300, 300);
deferred.resolve(canvas.toDataURL("image/png"));
};
return deferred.promise;
};
fetchImage = function(src) {
var deferred = $q.defer();
var xhr = new XMLHttpRequest();
xhr.responseType = 'blob';
xhr.onload = function() {
var url = URL.createObjectURL(xhr.response);
image = new Image();
resizeImage(url)
.then(function(dataUri) {
deferred.resolve(dataUri);
});
};
xhr.open('get', src);
xhr.send();
console.log(deferred.promise);
return deferred.promise;
};
$scope.picUrls = ["https://res.cloudinary.com/mediocre/image/upload/v1415293060/od9rkw2xtdtfsfiblq6k.png", "https://res.cloudinary.com/mediocre/image/upload/v1415293108/pgnbdgx0aamspgcxzwmx.png", "https://res.cloudinary.com/mediocre/image/upload/v1415294024/z7ohumjr5vs87e1nn5fl.png", "https://res.cloudinary.com/mediocre/image/upload/v1422407613/mzuce3ooqpcewddq9iih.png"];
$scope.picArray = [];
for (i = 0; i < $scope.picUrls.length; i++) {
console.log("executing loop")
$scope.picArray.push(fetchImage($scope.picUrls[i]));
}
$q.all($scope.picArray).then(function(imgArray) {
console.log("executing q.all statement");
$scope.picArray = imgArray;
console.log($scope.picArray);
});
}
]);
<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
</head>
<body>
<div ng-app="myApp" ng-controller="MyCtrl">
<div ng-repeat="pic in picArray">
<img src="pic">
</div>
</div>
</body>
</html>
Итак, я установил мои опечатки, как вы сказали, но [codepen] (HTTP : //codepen.io/anon/pen/pvrdaL? editors = 101) все еще имеет неожиданное поведение, о котором я говорил, - обрабатывается только последняя запись в массиве, а остальные - дубликаты пустых изображений. Также я не понимаю, почему мой оператор console.log в конце записывает объект обещания - я думал, что он будет записывать данные изображения, которые я назначил в обратном вызове. Редактировать: по какой-то причине исходный код не сохранялся, тот, что в этом комментарии, является новым, который я написал. – Soxad
@Soxad, у вас есть другие проблемы. См. Обновленный ответ –