如何解决在 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 举报,一经查实,本站将立刻删除。