【问题标题】:High frequency updates to PouchDB (Document update conflict)PouchDB 的高频更新(文档更新冲突)
【发布时间】:2017-06-03 18:20:15
【问题描述】:

我有一个获取/更新存储在 PouchDB 中的状态的方法。此方法由元素的构造函数调用,以将用户友好的唯一标记分配给元素。代码的简化版如下所示:

var tagList = [ /* set of dictionary words to cycle through */ ];
function generateTag(id) {
    return db.get('tags').then(function (tagData) {
        var tag = '', remainder = tagData.tagCount, quotient;

        while (remainder >= tagList.length) {
            quotient = Math.floor(remainder / tagList.length);
            tag += tagList[quotient - 1];
            remainder -= tagList.length * quotient;
        }
        tag += tagList[remainder];
        tag = tag.charAt(0).toLowerCase() + tag.slice(1);

        tagData.tagCount++;
        tagData.tags[tag] = id;

        db.put(tagData);
        return tag;
    }).catch(function (err) {
        console.error(err);
    });
}

class Element {
    constructor() {
        var self = this;
        generateTag('element' + Date.now()).then(function (tag) {
            self.tag = tag;
        });
    }
}

当创建元素之间存在延迟时,此逻辑按预期工作。但是,当元素以快速爆发(即 for 循环)创建时,db.get 调用第二个、第三个和连续元素在第一个元素的 db.put 操作完成之前被调用,从而导致“文档更新冲突”消息对于连续元素。起初我以为 PouchDB 的冲突解决会自动为我处理这个问题,但我错了。

也许我不理解处理此类情况的正确方法,或者有更好的方法来写这个吗?我需要的是连续的db.get 调用有效地阻止,直到来自先前操作的正在进行的db.put 完成。我在想甚至可能保留与“标签”对象上的最后一个 PouchDB 操作相对应的承诺的静态链接,这样我会运行 db.get('tags') 而不是 tagsPromise.then(function () { return db.get('tags'); }),但我仍然是一个有承诺的新手并且不要'不知道这是否是解决这个问题的理想方式,或者这个问题是否是一个真正的问题,或者我没有坚持更好的方法而强加给自己的东西?

更新: 看起来修改逻辑总是返回一个承诺,并且总是从一个“单例”承诺开始,而不是我提到的generateTag 函数中的db.get('tags') 确实解决了这个问题,仍然想了解是否有更好的方法。

【问题讨论】:

    标签: javascript promise pouchdb


    【解决方案1】:

    对于其他感兴趣的人,这就是我使用更新中提到的tagPromise 方法重写上述逻辑的方式(如果 PouchDB 专家有更好的答案,我会接受):

    var tagList = [ /* set of dictionary words to cycle through */ ];
    var tagPromise = db.get('tags');
    function generateTag(id, callback) {
        tagPromise = tagPromise.then(function() {
            return db.get('tags');
        }).then(function (tagData) {
            var tag = '', remainder = tagData.tagCount, quotient;
    
            while (remainder >= tagList.length) {
                quotient = Math.floor(remainder / tagList.length);
                tag += tagList[quotient - 1];
                remainder -= tagList.length * quotient;
            }
            tag += tagList[remainder];
            tag = tag.charAt(0).toLowerCase() + tag.slice(1);
    
            tagData.tagCount++;
            tagData.tags[tag] = id;
            callback(tag);
    
            return db.put(tagData);
        }).catch(function (err) {
            console.error(err);
        });
    }
    
    class Element {
        constructor() {
            var self = this;
            generateTag('element' + Date.now(), function (tag) {
                self.tag = tag;
            });
        }
    }
    

    【讨论】:

      【解决方案2】:

      我发现很难遵循您想要实现的目标。你能发布标签文档和元素和标签的例子吗?

      乍一看,获取和更新单个“标签”文档看起来很臭,我认为使用视图会更有意义。但是,为了获得知情的答复,我需要更多详细信息!谢谢!

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-03-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-05-23
        相关资源
        最近更新 更多