简体   繁体   中英

How to implement a throttle method in Vuejs?

Currently I'm working inside a chat application using webSockets. I've implemented a indicator which shows that one of the chat members is currently typing. I have another call which fires 5 seconds after the person starts typing to remove the indicator. The problem I'm having is that if the person continues to type longer than 5 seconds then the 'typing' indicator flashes in and out rapidly in the UI... Here is my current implementation.

sendChatState({ commit, dispatch, state }, payload) {
    connectionService.connection.setDialogChatState({dialogId: payload.visitId, conversationId: payload.visitId, chatState: 'composing'})
    // Create set timeout here to pause typing indicator...
    setTimeout(() => {
    connectionService.connection.setDialogChatState({dialogId: payload.visitId, conversationId: payload.visitId, chatState: 'pause'})
    }, 5000)
  },

Appears I may need to use some type of throttle to limit the amount of calls. However this is where I'm having trouble as I'm not entirely sure how to implement this.

You can solve it using debounce from lodash. Doing:

_.debounce(callServiceMethod, delay_time, { 'leading': true })

The debounce function is sending you back a throttled version of the function when you are calling it. In order to access it from the component scope and in the template within an eventHandler, the easiest way would be something like this:

import debounce from 'lodash/debounce'

export default {
  ...,
  methods: {
    sendChatState: debounce(function() {
            do your thing here 
    }, delay_time, { 'leading': true }),
  },
  ...
}

Note you need to use the config parameter to immediate call the method.

More info here .

Let's set the flag typing to FALSE at the beginning. On each change of the input value (meaning there is typing) you start a timer (and first cancel the previous timer, if there was an active one) and if the flag typing was FALSE - set it to TRUE and show the indicator (otherwise it has already been shown). Once the timer fires - you hide the indicator and set the flag typing to FALSE.

<template>
  <textarea v-model="message" @input="setFlag"/>
</template>

<script>
...
data()
{
  return {
    message: '',
    typing: false,
    timer: null,
  }
},
beforeDestroy()
{
  if (this.timer) clearTimeout(this.timer);
},
methods:
{
  setFlag()
  {
    if (this.timer) clearTimeout(this.timer);
    this.timer = setTimeout(this.timeOut, 5000);
    if (!this.typing)
    {
      this.typing = true;
      connectionService.connection.setDialogChatState({dialogId: payload.visitId, conversationId: payload.visitId, chatState: 'composing'});
    }
  },
  timeOut()
  {
    this.typing = false;
    connectionService.connection.setDialogChatState({dialogId: payload.visitId, conversationId: payload.visitId, chatState: 'pause'});
    this.timer = null;
  }
}
</script>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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