Цепочки обещаний в angularjs

Я загружаю вложения с помощью rest API в SharePoint 2013, для этого мне нужно вызвать метод загрузки вложений в синхронном режиме.

Потому что, если я вызываю асинхронный метод загрузки вложения, я получаю ошибку конфликта 409.

Как связать объекты обещания в цикле for.i.e. Я хочу вызвать второй метод вложения при первом успешном вложении и т.д.

Пожалуйста, помогите мне в лучшем подходе к цепочке обещаний в цикле for.

Распространенный способ сохранения вложений:

 var saveFileAngularJS = function (file, url) {
            var deferred = $q.defer();
            getFileBuffer(file).then(function (fileArrBuffer) {
                $http({
                    method: 'POST',
                    url: baseUrl + url,
                    headers: {
                        'Accept': 'application/json;odata=verbose',
                        'Content-Type': undefined,
                        'X-RequestDigest': jQuery("#__REQUESTDIGEST").val()
                    },
                    data: new Uint8Array(fileArrBuffer),
                    transformRequest: []                   
                }).then(function successCallback(data) {
                    deferred.resolve(data);
                    alert('Successfully saved.', data);
                }, function errorCallback(error) {
                    deferred.reject(error);
                    alert('Failed to save!!!.', error);
                });
            });
            return deferred.promise;
        };

Вызов метода:

for (var i = 0; i < $scope.files.length; i++) {
         var file = $scope.files[i]._file;
         var response = lssDealService.insertAttachment(transactionId, file);
}

 var insertAttachment = function (dealId, file) {
            var attachmentUrl = listEndPoint + "/GetByTitle('TransactionList')/GetItemById(" + dealId + ")/AttachmentFiles/add(FileName='" + file.name + "')";
            return baseService.saveFile(file, attachmentUrl);
        };

Вставка вложения вызовет метод SaveFile.

Я хочу запустить этот цикл for последовательно, после завершения цикла мне нужно обработать все обещания и отобразить пользователю сообщение об успешном выполнении.

Пожалуйста, помогите мне написать цепочку обещаний эффективным способом.


person Bhanuprakash Bysani    schedule 15.06.2016    source источник
comment
Вы можете обратиться к jsfiddle.net/jsengel/0ryvkvph.   -  person Nikhil Aggarwal    schedule 15.06.2016


Ответы (2)


Допустим, у вас есть вложения в виде массива,

function uploadMyAttachements() {
    return myAttachements.reduce(function(promise, attachment) {
        return promise.then(function () {
            return upload(attachment);
        })
        .then(function(result) {
            console.log('RESULT FOR LAST UPLOAD', result);
        });
    }, Promise.resolve());
}

function upload(attachment) {
    //upload the attachment to sharepoint
    //and return a promise here
}

uploadMyAttachements().catch(function(err) {
    //if anything in the promise chain fails
    //it stops then and there and CATCHED here
});

Теперь, что здесь происходит, используя Array.reduce, мы создаем цепочку промисов, как показано ниже.

upload(0).then(handleResult_0).upload(1).then(handleResult_1)....

и он выполняется один за другим, как вы ожидали

person Oxi    schedule 15.06.2016

Выкидываю свои 2 копейки:

$scope.attachments = []; //modified via binding.

function uploadAttachments(){
 //Reduce the files array into a promise array with the uploadOne method
 //then return the promise when every promise has been resolved or one has rejected.
 return $q.all($scope.attachments.reduce(uploadOne, []));
}

function uploadOne(file){
 //Upload one, return promise. Use $http or $resource.
}

//Note - a more advanced way of doing this would be to send the files as batch (one
//$http post) as FormData. There are some good wrappers for angular.

$scope.upload = function(){
 uploadAttachments().then(function(results){
  //Array of results
 }).catch(function(e){
  //Error handler
 });
}
person Muli Yulzary    schedule 29.06.2016