提问人:johann1301s 提问时间:7/2/2023 最后编辑:johann1301s 更新时间:7/2/2023 访问量:49
我可以通过只运行一次 reducer 来优化我的 Javascript 类,但保留所需的功能吗?
Can i optimize my Javascript class by only running reducer once, but keep the desired functionality?
问:
注意:在使用 react、redux、react-redux、redux-saga、redux-thunk、有和没有打字稿之后,我正在尝试为前端异步逻辑创建一个新的、更好的框架,具有 redux-saga(没有 redux-saga)和出色的打字稿支持。我已经做了一个很有前途的 MVP,但我还没有弄清楚 redux-saga 的功能。这是以下问题的背景。takeLatest
我的问题,是一个表演的主题。
我创建了一个名为 and a example 说明如何使用它。Actions
class Actions {
constructor() {
const actionNames = ['alpha', 'bravo', 'charlie', 'delta', 'echo', 'foxtrot', 'golf', 'hotel', 'india', 'juliet', 'kilo', 'lima', 'mike', 'november', 'oscar', 'papa', 'quebec', 'romeo', 'sierra', 'tango', 'uniform', 'victor', 'whiskey', 'x-ray', 'yankee', 'zulu'];
this.handler = (action) => console.log(`${action} was just executed.`)
Object.assign(this, {
cancel: () => {
this.handler = (cur) => console.log('Sorry, all actions are «cancelled».')
},
actions: actionNames.reduce((acc, cur) => ({
...acc,
[cur]: () => this.handler(cur)
}), {})
})
console.log('The reduce function was just executed!')
}
}
const {actions: actionsA, cancel: cancelA} = new Actions() // output: The reduce function was just executed!
actionsA.alpha() // output: alpha was just executed.
actionsA.foxtrot() // output: foxtrot was just executed.
cancelA()
actionsA.alpha() // output: Sorry, all actions are «cancelled».
actionsA.foxtrot() // output: Sorry, all actions are «cancelled».
const {actions: actionsB, cancel: cancelB} = new Actions() // output: The reduce function was just executed!
actionsB.alpha() // output: alpha was just executed.
actionsB.foxtrot() // output: foxtrot was just executed.
cancelB()
actionsB.alpha() // output: Sorry, all actions are «cancelled».
actionsB.foxtrot() // output: Sorry, all actions are «cancelled».
您可以运行添加的代码片段来验证输出。
问题来了!
是否有可能 - 以某种方式 - 避免在每次创建新实例时都运行 reducer?我知道这将涉及更改 的实现,但我非常希望实例的行为与上面的代码片段和示例中指定的一样。Actions
Actions
我的想法是,这可能是可能的,并且将是一个很好的优化,因为考虑到前端应用程序的性质,这将被调用很多次。new Actions()
我会尝试创建一个包装函数/闭包/工厂/生成器或生成该类的包装类。有关我目前正在尝试的示例,请参阅下面的示例。Actions
class ActionsGenerator {
constructor() {
const actionNames = ['alpha', 'bravo', 'charlie', 'delta', 'echo', 'foxtrot', 'golf', 'hotel', 'india', 'juliet', 'kilo', 'lima', 'mike', 'november', 'oscar', 'papa', 'quebec', 'romeo', 'sierra', 'tango', 'uniform', 'victor', 'whiskey', 'x-ray', 'yankee', 'zulu'];
this.handler = (action) => {}
const actions = actionNames.reduce((acc, cur) => ({
...acc,
[cur]: () => this.handler(cur)
}), {})
console.log('The reduce function was just executed in generator!')
Object.assign(this, {
Actions: class Actions {
constructor() {
// somehow implement the already created actions here. Is that possible?
}
}
})
}
}
const { Actions } = new ActionsGenerator() // output: The reduce function was just executed in generator!
const {actions: actionsA, cancel: cancelA} = new Actions() // <-- No output this time!
...
我希望我想要的程序的输出也会发生变化。
- reduce函数刚刚在生成器中执行!
- 阿尔法刚刚被处决。
- 狐步舞刚刚被处决。
- 对不起,所有操作都被«取消»。
- 对不起,所有操作都被«取消»。
- 阿尔法刚刚被处决。
- 狐步舞刚刚被处决。
- 对不起,所有操作都被«取消»。
- 对不起,所有操作都被«取消»。
如果有人碰巧确定这是不可能的,我将不胜感激。
这可能吗?
谢谢:)
答:
0赞
trincot
7/2/2023
#1
您可以使用代理作为属性的值。这样,您就不必构造(可能很大)对象。相反,代理层将在读取特定操作时返回正确的函数。actions
不是必需的,但我不会覆盖处理程序,而是使用一个属性,处理程序将使用它来决定要做什么。cancelled
class Actions {
static #actionNames = new Set(['alpha', 'bravo', 'charlie', 'delta', 'echo', 'foxtrot', 'golf', 'hotel', 'india', 'juliet', 'kilo', 'lima', 'mike', 'november', 'oscar', 'papa', 'quebec', 'romeo', 'sierra', 'tango', 'uniform', 'victor', 'whiskey', 'x-ray', 'yankee', 'zulu']);
#cancelled = false;
actions = new Proxy(this, {
get(obj, action) {
if (Actions.#actionNames.has(action)) return () => obj.handler(action);
}
})
constructor() {
this.cancel = () => this.#cancelled = true;
}
handler(action) {
if (this.#cancelled) {
console.log('Sorry, all actions are «cancelled».');
} else {
console.log(`${action} was just executed.`);
}
}
}
const {actions: actionsA, cancel: cancelA} = new Actions();
actionsA.alpha(); // output: alpha was just executed.
actionsA.foxtrot(); // output: foxtrot was just executed.
cancelA();
actionsA.alpha(); // output: Sorry, all actions are «cancelled».
actionsA.foxtrot(); // output: Sorry, all actions are «cancelled».
const {actions: actionsB, cancel: cancelB} = new Actions();
actionsB.alpha(); // output: alpha was just executed.
actionsB.foxtrot(); // output: foxtrot was just executed.
cancelB();
actionsB.alpha(); // output: Sorry, all actions are «cancelled».
actionsB.foxtrot(); // output: Sorry, all actions are «cancelled».
评论
0赞
johann1301s
7/2/2023
凉!我不知道代理!它似乎也更具有性能,用 和 进行测量。从我读到的关于代理的一点点来看,似乎可以使用陷阱而不是......?console.time
console.timeEnd
apply
get
0赞
trincot
7/2/2023
当调用方读取操作属性时,需要将陷阱放在返回的对象上。因此,您还需要更深地返回代理。这不会带来任何好处。apply
评论