JavaScript 代理:数组排序后聚合通知

问题描述 投票:0回答:2

我想找到一种在数组排序后仅获取一个通知的方法

有办法吗?谢谢你

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"
javascript arrays methods interceptor es6-proxy
2个回答
0
投票

您可以在 .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
投票

不使用代理的可行方法是使用

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>

© www.soinside.com 2019 - 2024. All rights reserved.