微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何限制由window.postMessage事件调用的函数

如何解决如何限制由window.postMessage事件调用的函数

我正在开发一个应用,其中我提出了不同的window.postMessage()请求来传递消息。当我用window.addEventListener('message',cb)收听消息时,我调用了另一个函数,但是有时我会收到对该函数的多次调用,因为这取决于我发布消息的次数。我创建了一个简单的节流功能,该功能很好,但不适用于函数调用。例如,假设当在1000ms调用函数三次时,该函数应被调用一次,而不是三个。

我想知道这是预期的行为,但是就我而言,该函数调用了三次。

我使用了this answer中的节流功能this也是我创建的小提琴示例,目的是为了了解我的意思。

function throttle(func,wait,options) {
    var context,args,result;
    var timeout = null;
    var prevIoUs = 0;
    if (!options) options = {};
    var later = function () {
      prevIoUs = options.leading === false ? 0 : Date.Now();
      timeout = null;
      result = func.apply(context,args);
      if (!timeout) context = args = null;
    };
    return function () {
      var Now = Date.Now();
      if (!prevIoUs && options.leading === false) prevIoUs = Now;
      var remaining = wait - (Now - prevIoUs);
      context = this;
      args = arguments;
      if (remaining <= 0 || remaining > wait) {
        if (timeout) {
          clearTimeout(timeout);
          timeout = null;
        }
        prevIoUs = Now;
        result = func.apply(context,args);
        if (!timeout) context = args = null;
      } else if (!timeout && options.trailing !== false) {
        timeout = setTimeout(later,remaining);
      }
      return result;
    };
  }

  document.getElementById("btn").addEventListener(
    "click",throttle(function () {
      console.log("BUTTON CLICKED");
    },1000)
  );

  window.addEventListener("message",({ data }) => {
    if (data.type === "viewer:clear:cache") {
      throttle(test(),1000);
    }
  });

  function test() {
    console.log("TEST CALLED");
  }

  for (let i = 0; i < 5; i++) {
    window.postMessage({ type: "viewer:clear:cache" },"*");
  }
    <button id="btn">CLICK ME</button>

解决方法

请注意在点击处理程序的情况下,如何将throttle的返回值传递给addEventListener。在消息事件的情况下,您要在事件处理程序内部调用throttle,而忽略返回值。

您也没有传递要节流的函数,而是传递了test()返回值。即您先呼叫test,然后将undefined传递给throttle。这就是为什么每次调用消息事件处理程序时都会调用test的原因。

您需要的是:

window.addEventListener("message",throttle(({ data }) => {
  if (data.type === "viewer:clear:cache") {
    test();
  }
},1000));

throttle返回一个新函数,并且是接收事件后需要调用的那个函数。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。