使用angularjs将多个独立附件上载到couchdb

时间:2013-09-17 20:26:45

标签: javascript angularjs couchdb

我正在尝试使用angularjs将多个文件上传到couchdb文档。我试图使用angular.forEach循环来做到这一点,但是这会因为循环继续而不等待前一个循环完成其异步$ http调用而失败。 这就是我的代码目前的样子:

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是$ http HEAD调用,返回保存附件的文档的当前修订版ID的承诺。 couch.uploadAttachment是$ http PUT调用,用于保存对文档的附件。这个代码适用于第一个文件,不幸的是,代码以异步方式运行循环的下一次运行,然后第一个运行PUT前一个附件,因此couch.getRevisionId返回与前一个调用相同的修订版ID,导致代码失败409尝试将附件保存到更新的文档时发生冲突。 有没有办法延迟后续循环,直到getRevisionId和uploadAttachment promises返回后?

1 个答案:

答案 0 :(得分:1)

您可以按照Q documentation中关于序列的描述链接承诺,但使用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();

查看完整示例here

如果您的CouchDB服务已经依赖$q,那么您可能不需要将异步任务包含在另一个更高级$q的承诺中。