Application of debounce function and execution sequence of parent-child cycles in js

Anti shake function debounce() in js

When developing a website, we sometimes need to monitor certain events all the time. When the event is triggered, we visit the background and request data. However, we know that if the web page on the mobile phone is when we request a large amount of data every time, we need to refresh the page length to effectively use better scroll, but too frequent refreshing will also affect the efficiency. For example, when viewing some shopping malls on the mobile phone, If you keep sliding down, there will always be data requests and the page length will always be refreshed

However, refreshing the length of the image every time you request will lead to too frequent. If every request

<img :src="goodsItem.show.img" alt="" @load="imageLoad">

When the picture is loaded, the imageLoad operation is triggered

  methods: {
    imageLoad() {
      this.$bus.$emit('itemImageLoad')
      Someone will ask why it is used here $bus To emission function? Because in this project, the component where the picture is located goodsListItem The component that calls the picture is goodslist Component instead of calling goodslist Component and the component listening for the event home.vue And actually perform the refresh operation scroll Yes scroll Component, so it's too complicated to pass information through parent-child, so just set one bus Bus, listening for events and delivering messages
    },
  },

In the imageLoad function, the emit function is the function that emits the itemImageLoad event

Vue.prototype.$bus = new Vue()

The $bus has already been defined in the Vue prototype, so you can call the emit function

this.$bus.$on('itemImageLoad',() => {
      // this.$refs.scroll && this.$refs.scroll.refresh()
      refresh()
    })

After sending, listen on the home side, trigger the event, and execute refresh(), that is, refresh the height of the picture. Someone will ask, since you want a group of pictures to request once, why not refresh the height after the request is completed? In fact, the anti jitter we need to do is to use this idea, but if you want to refresh the height immediately upon request, it is not feasible. Why? Because you request a group of pictures, but the data is obtained one by one, or one character by one, so the actual height also changes bit by bit. If you refresh the height immediately after requesting the data, your better scroll height can be said to be unchanged. With good luck, it will grow a little longer, but the pictures will follow one after another, and the actual height continues to increase, so we'd better, Refresh the height of better scroll every time a picture comes,
But this refresh is too frequent. Can we refresh it just after it requests a set of data? Can you refresh the height when its network speed is bad, a group of data requests are very slow, and it gets stuck in the middle? So that they can access the requested pictures?
Yes, our debounce() anti jitter processing is used here

Parent child component cycle execution sequence

It's interesting to execute this code first debounce Function,
Then return the anonymous function and assign it to refresh,But at this time, the anonymous function is not executed, because you just return, and refresh No parentheses, so it's just a function variable. And the real execution is triggered itemImageLad Post execution refresh of

As for why this code should be placed in mounted Instead of created In, you can view my last article, because if you put it in created In, it is very likely that the subcomponent cannot be found scroll Other related undefined Error because the parent component is the first created Yes, and mounted You have to wait until the subcomponent is missing mounted After that
mounted:{
	const refresh = this.debounce(this.$refs.scroll.refresh, 200)
	    this.$bus.$on('itemImageLoad',() => {
	      // this.$refs.scroll && this.$refs.scroll.refresh()
	      refresh()
	    })
 }
//The real refresh height function is actually in this$ refs. scroll. When middle note is called in refresh, we assign the return function to refresh in the debounce function, and then call refresh when itemImageLoad is triggered.
    

debounce(func, delay) {
      let timer = null
      return function (...args) {
        if (timer) clearTimeout(timer)

        timer = setTimeout(() => {
          func.apply(this,args)
        },delay)
      }
    },

In debounce, a timer is set and executed after 0.2s. The first timer is set to null. Join. After the first picture is loaded, the debounce function is executed and the timer is empty. Therefore, a timer is set and func, that is, scroll. Is executed after 0.2s Refresh(), if the loading of the second image is completed within 0.2, continue to trigger refresh, that is, the anonymous function returned in debounce, and the timer exists, we will clearTimeout and continue to set a timer. Similarly, if the loading of the third image is completed within 0.2s, continue to clear the timer and then set a new timer.
The above is the practical application of the anti shake function. Of course, I have another question: why does the timer survive when it is re operated by refresh again and again? It is reasonable that the timer should be gone when the second refresh is executed. Because the first refresh is the first refresh and the second refresh is the second, it is a little unclear. Unless the scope of the let is a block level scope, the timer always exists in the refresh. I can only explain it myself.

Tags: Front-end Vue Javascript

Posted by s1m0n on Sun, 17 Apr 2022 00:07:03 +0930