我想找到一种在数组排序后仅获取一个通知的方法
有办法吗?谢谢你
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"
您可以在 .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>
不使用代理的可行方法是使用
around
方法修饰符的通用实现。后者可以看作是函数包装的特例。
这样的修饰符接受两个函数,
proceed
和handler
以及target
对象作为其3个参数。它确实返回一个函数,该函数将再次返回 handler
函数的结果。后者确实在(可选)提供的 target
的上下文中被调用,同时还传递了 proceed
函数、其自己的 handler
引用和修改后的函数的 arguments
数组。
因此,基于这样的修改器,OP可以通过修改例如来实现预期的行为:像这样的数组实例的
sort
方法 ...
const arr = [2, 1];
// reassign the array instance's specifically modified `sort`.
arr.sort = around(arr.sort, notifyAboutFinishedTask, arr);
...其中
notifyAboutFinishedTask
是 handler
函数,它准确地实现了 OP 正在寻找的内容...
“...数组排序后只有一个通知”
...示例代码...
// 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>