【问题标题】:Doesn't add records into PouchDB when used same function over again再次使用相同功能时不会将记录添加到 PouchDB
【发布时间】:2020-01-30 22:13:01
【问题描述】:

我正在尝试创建一个包含“用户”及其数据的数据库。奇怪的是,当我第三次尝试时,它并没有 put() 新变量。为此,我创建了一个本地数据库dblocal,并将这个数据库复制到名为dbremote 的远程数据库。首先,我创建一个包含一个变量的文档。

function newuser() {
    if (window.document.consent_form.consent_to_share.value) {
        var id = "p" + Date.now() + "-" + Math.floor(Math.random() * 10000);
        var dblocal = new PouchDB(id);
        var consenttoshare = window.document.consent_form.consent_to_share.value;
        document.cookie = id;
        var dbremote = 'http://localhost:5984/experiment';
        dblocal.put({
            _id: id,
            consent: consenttoshare
        });
        dblocal.replicate.to(dbremote, {live: true});
    }
}

这一切都很好,在另一个 js 文件中,我试图通过执行以下函数 putdb() 将变量添加到同一个文档中。我按以下方式执行此操作(如他们的文档中所述是正确的方式):

function putdb () {
    if (document.cookie){
        var id = document.cookie;
        var loggedin = "True";

        var dblocal = new PouchDB(id);
        dblocal.get(id).then(function (doc) {
            doc.loggedin = loggedin;
            return dblocal.put(doc);
        }).then(function () {
            return dblocal.get(id);
        }).then(function (doc) {
            console.log(doc);
            var dbremote = 'http://localhost:5984/experiment';
            dblocal.replicate.to(dbremote, {live: true});
        });
    }
}

这成功地将变量loggedin 添加到了我想要的文档中。但是,在第三次尝试向该文档添加信息时(再次在另一个 js 文件中),没有任何反应。我使用了与以前完全相同的方法,但只使用了不同的变量。

function putdb (checked) {
    if (document.cookie) {
        var id = document.cookie;
        var checkedlist = [];    
        for (i = 0; i < checked; i++) {
            checkedlist.push($("input[type=checkbox]:checked")[i].value)
        }
        var playlistname = document.getElementById("playlistname").value;

        var dblocal = new PouchDB(id);
        dblocal.get(id).then(function (doc) {
            doc.checkedlist = checkedlist;
            doc.playlistname = playlistname;
            return dblocal.put(doc);
        }).then(function () {
            return dblocal.get(id);
        }).then(function (doc) {
            console.log(doc);
            var dbremote = 'http://localhost:5984/experiment';
            dblocal.replicate.to(dbremote, {live: true});
        });
    }
}

我检查了所有变量,它们是正确的。 我尝试了纯文本变量。 该脚本确实运行。 我尝试像第一次那样在文档中添加信息。 所有这些似乎都没有像我在最后一个函数中想要的那样向文档添加另一个变量。我认为这与我不知道的 pouchDB 的工作方式有关。非常感谢您的帮助!

【问题讨论】:

  • 随着时间的推移创建和忘记这样的本地数据库可能会创建一个 巨大 的废弃 IndexedDB pouch 实例(浪费用户空间)。为所有用户使用具有一致名称的单个数据库。此外,您的 _id 存在风险,因此请准备好处理 409。由于您的 _id 不传达信息,请考虑使用 uuidjs/uuid 或类似的。
  • 事实证明,问题出在异步代码上。该函数没有完全检索到承诺,但已经转到下一页。

标签: javascript couchdb pouchdb


【解决方案1】:

您的代码中有许多问题会导致 PouchDB 使用不当,并可能导致问题。

首先,给文档赋予与数据库名称相同的 id 没有多大意义。假设您希望每个用户一个数据库的方法,您可以采用两种方法。

多文档方法 相反,您可以在同一个数据库中创建多个具有不同 ID 的文档。例如,您的“同意”信息可能会这样存储:

var id = "p" + Date.now() + "-" + Math.floor(Math.random() * 10000);
let dblocal = new PouchDB(id);
document.cookie = id;
let dbremote = 'http://localhost:5984/experiment';
dblocal.put({
    _id: "consent",
    consent: window.document.consent_form.consent_to_share.value
});
dblocal.replicate.to(dbremote, {live: true});

虽然您的播放列表信息是这样存储的:

dblocal.put({
    _id: "playlist",
    name: playlistname,
    itemsChecked: checkedlist
});

单文档方法 第二个选项是存储单个文档,其中包含您要存储的与用户关联的所有信息。在这种方法中,您将需要获取现有文档并在有新信息时对其进行更新。假设您将文档命名为 global-state(即将第一个代码 sn-p 中的“consent”替换为“global-state”),以下代码将更新文档:

dblocal.get("global-state").then((doc)=>{
    doc.loggedIn = true; // or change any other information you want
    return dblocal.put(doc);
}).then((response)=>{
    //handle response
}).catch((err)=>{
    console.log(err);
});

此外,您应该只调用

dblocal.replicate.to(dbremote, {live: true});

函数一次,因为“实时”选项指定将来的更改将自动复制到远程数据库。

【讨论】:

  • 有没有首选的方法将用户保存到数据库?每个用户都有自己的数据库,或者每个用户都是数据库中的一个文档。
  • @KenGeelhoed 这取决于您的项目规范。如果插入的数据在您的应用程序过程中发生更改,则可能更适合使用全局状态并更新它。如果您的数据大部分是静态的(例如日志文件),那么创建新文档会容易得多。
猜你喜欢
  • 2013-10-16
  • 1970-01-01
  • 2021-03-18
  • 2019-10-30
  • 1970-01-01
  • 1970-01-01
  • 2021-03-21
  • 1970-01-01
  • 2019-10-14
相关资源
最近更新 更多