提问人:tit 提问时间:7/28/2023 最后编辑:Peter Seligertit 更新时间:8/23/2023 访问量:54
JavaScript 代理:数组排序后聚合通知
JavaScript proxies : aggregate notifications after array sort
问:
我想找到一种方法,在数组排序后只收到一个通知
有办法吗?谢谢
const callback = function () {
console.log (...arguments)
}
const array = [2,1]
const handler = {
set (target, prop, value, receiver) {
callback (prop, value)
return Reflect.set (target, prop, value, receiver)
}
}
const proxy = new Proxy (array, handler)
proxy.sort()
// calls two times callback
// prints "0" 1 and "0" 2
// would like one notification : "array sorted"
答:
0赞
InSync
7/28/2023
#1
您可以在其本身上使用 .apply()
陷阱:Array#sort()
console.config({ maximize: true });
Array.prototype.sort = new Proxy(Array.prototype.sort, {
apply(target, thisArg, argumentList) {
const sortedThis = Reflect.apply(target, thisArg, argumentList);
console.log('sorted');
return sortedThis;
}
});
console.log([2, 1].sort());
<script src="https://gh-canon.github.io/stack-snippet-console/console.min.js"></script>
...或者,如果您希望代理仅影响您的数组,则可以返回一个自定义函数,如果被访问的函数是:property
'sort'
console.config({ maximize: true });
const proxy = new Proxy([2, 1], {
get(target, property, receiver) {
if (property === 'sort') {
return function(comparer) {
const originalSort = Reflect.get(target, property, receiver);
const sortedThis = originalSort.apply(target, [comparer]);
console.log('sorted');
return sortedThis;
}
}
return Reflect.get(target, property, receiver);
}
});
console.log('.sort() works:', proxy.sort());
console.log('.slice() is fine too:', proxy.slice(1));
<script src="https://gh-canon.github.io/stack-snippet-console/console.min.js"></script>
评论
0赞
tit
7/28/2023
完善。get 实现更适合我的用例。谢谢
0赞
tit
7/28/2023
注意:不会调用''set',这没关系!
1赞
Peter Seliger
8/23/2023
#2
一种不使用代理的可行方法是使用周围
方法修饰符的通用实现。后者可以看作是功能包装的一个特殊案例。
这样的修饰符接受两个函数,以及一个 -object 作为其 3 个参数。它确实返回一个函数,该函数将再次返回函数的结果。后者确实在提供的(可选)上下文中被调用,同时也被传递了 -function、它自己的 -reference 和修改后的函数的 -array。proceed
handler
target
handler
target
proceed
handler
arguments
因此,基于这样的修饰符,OP 可以通过修改例如数组实例的 -method 来实现预期的行为,例如这样的 ...sort
const arr = [2, 1];
// reassign the array instance's specifically modified `sort`.
arr.sort = around(arr.sort, notifyAboutFinishedTask, arr);
...哪里是实现 OP 正在寻找的东西的功能......notifyAboutFinishedTask
handler
"...数组排序后只有一个通知”
...示例代码 ...
// implementation of `sort`-specific `around`-handler.
function notifyAboutFinishedTask(proceed, handler, args) {
const arr = this;
// original task.
proceed.apply(arr, args);
// additional notification.
console.log('\narray sorted');
console.log('arr ...', arr);
console.log('arguments ...', args);
}
const arr = [2, 1];
console.log('unsorted arr ...', arr);
// reassign the array instance's specifically modified `sort`.
arr.sort = around(arr.sort, notifyAboutFinishedTask, arr);
// invoking sort twice, once with and once without sort function.
arr.sort();
arr.sort((a, b) => b - a);
.as-console-wrapper { min-height: 100%!important; top: 0; }
<script>
// implementation of an `around` modifier.
function around(proceed, handler, target) {
return function (...args) {
return handler.call(target ?? null, proceed, handler, args);
};
}
</script>
评论
1赞
tit
8/28/2023
嗨,我还需要让它在代理中工作,该代理也管理访问器。但是,您的答案非常接近,甚至更接近......我喜欢您提供的链接,我尝试在这里总结一下(仅代码):gist.github.com/thipages/085aa96a70231b6c54c0660514bfc858。Thnak 你。
0赞
Peter Seliger
8/28/2023
@tit......说到链接和您提供的要点,实际上有一个我的回购,它确实实现了......“原型和非原型的,可能是可取的,JavaScript/ECMAScript 函数或方法修饰符,允许在此类修改后的函数/方法的调用/应用/执行时间,根据其参数、返回值和上下文拦截、内省和操作函数或方法的控制流。”
1赞
tit
8/28/2023
是的,我看到了 git 库,感谢您的所有论文/loc/so。要点是,我只是试图有一个更短的代码,可以一目了然地理解,并添加一些我的语义(哎呀!
评论