简体   繁体   English

你如何在 ReactJS 中限制静态方法?

[英]How do you throttle a static method in ReactJS?

I am trying to write a Nylas N1 plugin, and so I started by just modifying the built-in spellcheck (here https://github.com/nylas/N1/blob/master/internal_packages/composer-spellcheck/lib/spellcheck-composer-extension.es6 ).我正在尝试编写 Nylas N1 插件,所以我从修改内置拼写检查开始(这里是https://github.com/nylas/N1/blob/master/internal_packages/composer-spellcheck/lib/spellcheck- composer-extension.es6 )。 I imported the underscore library, and tried to throttle the _wrapMisspelledWords function:我导入了下划线库,并尝试限制 _wrapMisspelledWords 函数:

import _ from 'underscore';
...
export default class SpellcheckComposerExtension extends ComposerExtension {
  ...
  static onContentChanged({editor}) {
    SpellcheckComposerExtension.update(editor);
  }

  static update = (editor) => {
    SpellcheckComposerExtension._unwrapWords(editor);
    SpellcheckComposerExtension._wrapMisspelledWords(editor);
  }

  static _wrapMisspelledWords = _.throttle((editor) => {
    console.log('wrap mispelled words');
    ...
    ...
  }, 2000)
  ...
}

It appears to throttle correctly at first, and then seems to get stuck in some loop, constantly repeating output from previous changes.它起初似乎节流正确,然后似乎卡在某个循环中,不断重复先前更改的输出。 I have read through another thread ( Perform debounce in React.js ) but can't figure out why this behavior is happening.我已经阅读了另一个线程( 在 React.js 中执行去抖动),但无法弄清楚为什么会发生这种行为。

EDIT:编辑:

It might make more sense to throttle the update function, but I see the same issue.限制更新功能可能更有意义,但我看到了同样的问题。

EDIT:编辑:

OK instead of throttling or debouncing, I decided to wrap the update function in setTimeout(..., 0) in order to debug, and still shows this same issue.好的,而不是限制或去抖动,我决定将更新函数包装在 setTimeout(..., 0) 中以进行调试,并且仍然显示相同的问题。

The conditions for entering an infinite loop seem to be:进入无限循环的条件似乎是:

  • there is at least one spelling mistake (so that unwrap and wrap say that they've modified the content)至少有一个拼写错误(所以 unwrap 和 wrap 表示他们已经修改了内容)
  • the update function is added to the event queue instead of firing immediately (using setTimeout, throttle or debounce)更新函数被添加到事件队列而不是立即触发(使用 setTimeout、throttle 或 debounce)

The contenteditable component ( https://github.com/nylas/N1/blob/1b4739335f4452faa720914309c5e6a593db531d/src/components/contenteditable/contenteditable.cjsx#L302-L333 ) has a mutation observer that stops listening while the extensions run, and I think when I add my update to the event queue, it starts listening for mutations before the update can run, causing another mutation to be observed, entering the infinite loop. contenteditable 组件( https://github.com/nylas/N1/blob/1b4739335f4452faa720914309c5e6a593db531d/src/components/contenteditable/contenteditable.cjsx#L302-L333 )有一个突变观察者,当我认为扩展程序停止监听时,它会停止监听我将我的更新添加到事件队列中,它在更新可以运行之前开始侦听突变,导致观察到另一个突变,进入无限循环。

Any solutions, or tips?任何解决方案或提示?

I know this is a bit late here, but I've done this same thing before.我知道这有点晚了,但我以前做过同样的事情。

class Thing {
  static someFn() {
    // whatever you do
  }

  static heavyAJAX() {
    // some heavy ajax
  }
}

Thing.someFn = _.throttle(Thing.someFn, 2000);
Thing.heavyAJAX = _.debounce(Thing.heavyAJAX, 1000);

This pattern has worked for me with throttle and debounce .这种模式对我debounce throttledebounce You can also use the same approach with instance methods.您也可以对实例方法使用相同的方法。 If our methods weren't static , you would just use Thing.prototype :如果我们的方法不是static ,您只需使用Thing.prototype

Thing.prototype.someFn = _.throttle(Thing.prototype.someFn, 2000);
Thing.prototype.heavyAJAX = _.debounce(Thing.prototype.heavyAJAX, 1000);

If you were to do this with instance methods, I would suggest a composure approach in the constructor:如果您要使用实例方法执行此操作,我建议在构造函数中采用一种镇定方法:

class Thing {
  constructor() {
    this.someFn = _.throttle(this.someFn, 2000);
  }

  someFn() {
    // your things...
  }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM