微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

在 lodash 链接“_.chain()”中返回父对象

如何解决在 lodash 链接“_.chain()”中返回父对象

我正在使用一个库 (lowdb),它在后台使用 lodash 在 json 文件中创建本地数据库。我想知道的是如何在修改 child 修改一个之后在 lodash 链接中到达父对象,例如。

const low = require('lowdb');
const FileSync = require('lowdb/adapters/FileSync');

const adapter = new FileSync('db.json');
const db = low(adapter);

/*
Eg. DB structure:
{
  "posts": [
    {
      "id": 1,"title": "post1"
    },{
      "id": 2,"title": "post2"
    },{
      "id": 3,"title": "post3"
    }
  ]
}
*/

db
  .get('posts')
  .find({ id: 2 })
  .assign({ title: 'edited title' }) 
  //after that I want to go back to posts to edit another one in the same chain
  .write();

我知道它可以在多个调用中完成,但我想知道是否可以在一个链中完成。

解决方法

简答

如果您的目标是使代码尽可能好看,我建议您使用 lodash-id 及其 updateById 函数。我在冗长的回答中介绍了所有可能的解决方案,但我个人会避免直接链接,而是执行以下操作:

const lodashId = require('lodash-id');
const low = require('lowdb');
const FileSync = require('lowdb/adapters/FileSync');

const adapter = new FileSync('db.json');
const db = low(adapter);
db._.mixin(lodashId);

const posts = db.get("posts");
posts.updateById( 1,{ title: 'edited title 1' }).commit();
posts.updateById( 2,{ title: 'edited title 2' }).commit();
posts.updateById( 3,{ title: 'edited title 3' }).commit();
posts.write();

长答案

有几种方法可以解决这个问题,目前为止 updateById 并不是唯一的方法。事实上,也可以使用 tap 函数在一个链中执行此操作。下面我介绍几个备选方案。

我可以在浏览器中快速试用这些功能吗?

当然!我实际上制作了一个 Codepen,您可以直接在浏览器中尝试所有不同的可能方法,只需记住打开浏览器控制台查看测试结果!链接在这里: https://codepen.io/jhack_jos/pen/XWNrpqX

如何调用函数?

所有这些函数都接收一个适配器作为输入。你可以这样称呼他们:

const result = testcaseXY(adapter);

1A) 点击并查找+分配

function testcase1A(adapter)
{
  const db = low(adapter);
  return db
    .get("posts")
    .tap( (posts) => _.chain(posts).find({ id: 1 }).assign({ title: 'edited title 1' }).commit())
    .tap( (posts) => _.chain(posts).find({ id: 2 }).assign({ title: 'edited title 2' }).commit())
    .tap( (posts) => _.chain(posts).find({ id: 3 }).assign({ title: 'edited title 3' }).commit())
    .write();
}

什么是tap

  • 它是来自 lodash 的实用函数
  • 它不会直接改变数据库
  • 但是,它确实将对象持有的引用传递给 interceptor 函数(在本例中我使用了箭头函数)
  • 对值的引用可以改变,从而影响数据库内部的对象
  • 在数据库上调用 .write() 使更改具有决定性。

2A) 点击并查找+设置

function testcase2A(adapter)
{
  const db = low(adapter);
  _.mixin(lodashId);
  return db
    .get("posts")
    .tap( (posts) => _.chain(posts).find({ id: 1 }).set("title",'edited title 1').commit())
    .tap( (posts) => _.chain(posts).find({ id: 2 }).set("title",'edited title 2').commit())
    .tap( (posts) => _.chain(posts).find({ id: 3 }).set("title",'edited title 3').commit())
    .write();
}

什么是set

  • 这是执行 .assign 所做的事情的一种稍微短一些的方法,但仅适用于一个属性。
  • 您可能希望 .set.assign

3A) 点击 & updateById

function testcase3A(adapter)
{
  const db = low(adapter);
  _.mixin(lodashId);
  return db
    .get("posts")
    .tap( (posts) => _.chain(posts).updateById( 1,{ title: 'edited title 1' }).commit())
    .tap( (posts) => _.chain(posts).updateById( 2,{ title: 'edited title 2' }).commit())
    .tap( (posts) => _.chain(posts).updateById( 3,{ title: 'edited title 3' }).commit())
    .write();
}

什么是updateById

  • 这是一个由 lodash-id library 公开的函数
  • 您必须首先将其作为 mixin 添加到 lowdb 中
  • 要这样做,您首先需要使用 const lodashId = require('lodash-id')
  • 然后你需要调用 db._.mixin(lodashId);
  • 这里我直接调用 _.mixin(lodashId),因为我直接在 tap 函数中使用了 lodash,而没有通过 lowdb

1B) 临时变量 & find+assign

function testcase1B(adapter)
{
  const db = low(adapter);
  const posts = db.get("posts");
  posts.find({ id: 1 }).assign({ title: 'edited title 1' }).commit();
  posts.find({ id: 2 }).assign({ title: 'edited title 2' }).commit();
  posts.find({ id: 3 }).assign({ title: 'edited title 3' }).commit();
  return posts.write();
}

如您所见,在此处使用临时变量可为我们提供更紧凑的代码,从而更易于阅读、调试和重构。

2B) 临时变量 & find+set

function testcase2B(adapter)
{
  const db = low(adapter);
  const posts = db.get("posts");
  posts.find({ id: 1 }).set("title",'edited title 1').commit();
  posts.find({ id: 2 }).set("title",'edited title 2').commit();
  posts.find({ id: 3 }).set("title",'edited title 3').commit();
  return posts.write();
}

3B) 临时变量和 updateById

function testcase3B(adapter)
{
  const db = low(adapter);
  db._.mixin(lodashId);
  const posts = db.get("posts");
  posts.updateById( 1,{ title: 'edited title 1' }).commit();
  posts.updateById( 2,{ title: 'edited title 2' }).commit();
  posts.updateById( 3,{ title: 'edited title 3' }).commit();
  return posts.write();
}

感谢您的阅读!

我很乐意提供任何进一步的解释,如果您需要的话。 作为奖励,我想补充一点,可以编写一些巧妙的实用函数作为 lowdb/lodash mixin,以使我们能够使用更短的语法并仍然正确地链接。然而,这可能比您想要的更多。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。