天道酬勤,学无止境

Uploading multiple standalone attachments to couchdb using angularjs

I am trying to upload multiple files to a couchdb document using angularjs. I have attempted to do this using an angular.forEach loop, however this fails as the loop continues without waiting for the previous loop to finish its asynchronous $http calls. This is how my code looks at the moment:

angular.forEach($scope.fileList, function(value, key){
    couch.getRevisionId($scope.plan._id)
    .then(function(response){
        couch.uploadAttachment($scope.plan._id, response[1], value[0])
            .then(function(response2){
        console.log("Response2", response2);
        }, 
        function(reason2){
        console.log("Reason2", reason);
        });
    },
    function(reason){
        console.log("GetrevisionId failed reason=", reason)
   });
});

couch.getRevisionId is an $http HEAD call returns a promise of the current revision id of the document the attachment is being saved to. couch.uploadAttachment is an $http PUT call which saves the attachment to the document. This code works for the first file, unfortunately as the code runs asynchronously the next run of the loop runs before the first has PUT the previous attachment and so couch.getRevisionId returns the same revision id as the previous call, causing the code to fail with a 409 conflict as it attempts to save the attachment to an updated document. Is there a way of delaying subsequent loops until after the getRevisionId and uploadAttachment promises have returned?

评论

You could chain promises as described in the Q documentation about sequences, but using the Angular $q API

var asyncTask = function (value) {
    var deferred = $q.defer(); 
    ...
    return deferred.promise;
};

var list = [ ... ];

var deferred = $q.defer();
var promise = deferred.promise;
angular.forEach(list, function (value) {
    promise = promise.then(function () {
        return asyncTask(value);
    });
});
deferred.resolve();

See a complete example here.

If your CouchDB service already relies on $q then you might not need to wrap your async task inside another higher level $q promise.

受限制的 HTML

  • 允许的HTML标签:<a href hreflang> <em> <strong> <cite> <blockquote cite> <code> <ul type> <ol start type> <li> <dl> <dt> <dd> <h2 id> <h3 id> <h4 id> <h5 id> <h6 id>
  • 自动断行和分段。
  • 网页和电子邮件地址自动转换为链接。

相关推荐