1

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

4

1 回答 1

1

您可以按照Q 文档中关于序列的描述链接承诺,但使用 Angular $qAPI

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();

在此处查看完整示例。

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

于 2013-09-17T21:31:30.577 回答