【问题标题】:Uploading multiple standalone attachments to couchdb using angularjs使用angularjs将多个独立附件上传到couchdb
【发布时间】:2013-09-18 05:38:11
【问题描述】:

我正在尝试使用 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 承诺返回之后?

【问题讨论】:

    标签: javascript angularjs couchdb


    【解决方案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 承诺中。

    【讨论】:

    • 感谢您的示例和 jsFiddle 示例。由于我的问题需要解决两个承诺,因此我需要将它们链接到 angular.forEach 中。我改编了你的小提琴,我的版本可以在here 找到。精彩的回答,谢谢。
    • 这很酷。我试图通过避免$scope.revisionId 的必要副作用来简化您的工作。你可以在这里查看jsfiddle.net/7bcbm/1
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-02-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-31
    • 1970-01-01
    相关资源
    最近更新 更多