PeachScript / vue-infinite-loading

An infinite scroll plugin for Vue.js.
https://peachscript.github.io/vue-infinite-loading/
MIT License
2.67k stars 369 forks source link

$InfiniteLoading:reset and scroll event may trigger concurrent attemptLoad and force application to send two same ajax requests. #189

Closed DustinPT closed 6 years ago

DustinPT commented 6 years ago

Version

2.3.5

Vue.js version

2.5.16

Reproduction Link

https://codepen.io/dustinpt/pen/bmxMVm

Steps to reproduce

What is Expected?

snapshots

Two request snapshot from chrome dev tool:

First request:

emit_reset

Second request:

scroll_triggered
PeachScript commented 6 years ago

Could you provide a reproduce link?

DustinPT commented 6 years ago

Could you provide a reproduce link?

I have create one at codepen: https://codepen.io/dustinpt/pen/bmxMVm

PeachScript commented 6 years ago

Hi @DustinPT , I think it is a expected result after test your demo over and over again.

For example, a user visiting this official demo, he has browsed 3 pages then he scroll down and try to browse the 4th page, but the http request is always pending, so he decided change the news type to browse other news, if we ignore his action, until the loaded method be called, is it very terrible?

So in this case, I think it is not send 2 same http request but is 2 different http requests, because the reset event means this plugin completes a lifecycle and restart a new one.

DustinPT commented 6 years ago

Hello @PeachScript , Our problem scene is different from what you said. We have a search page. Sometimes, when the user clicks the search button, two pages of the same data appear on the page. After debugging, we found that after clicking the search button, the page issued two identical ajax requests at the same time. Our page processing code is very simple. After clicking the search button, the data list is cleared and a reset event is issued to vue-infinite-loading. Later we looked at the code of vue-infinite-loading, the problem should be like this. After clearing the data list, the scroll event may be issued when the page is re-rendered. When the vue-infinite-loading component processes both the scroll event and the reset event, two data requests may be issued at the same timing.

time reset event thread scroll event thread
1 event received
2 InfiniteLoading.vue:192
3 event received
4 InfiniteLoading.vue:144
5 InfiniteLoading.vue:150
6 InfiniteLoading.vue:251
7 InfiniteLoading.vue:145
8 InfiniteLoading.vue:251
PeachScript commented 6 years ago

Hi @DustinPT , thanks for your detailed explanation! I've reproduced this problem on my computer, and fixed it with the v2.4.1, you can try it now, please comment here if this problem still exists.

Best Regards.

DustinPT commented 6 years ago

Hi @DustinPT , thanks for your detailed explanation! I've reproduced this problem on my computer, and fixed it with the v2.4.1, you can try it now, please comment here if this problem still exists.

Best Regards.

OK, I will upgrade to the latest version and test it, thanks for your work.

lucassonsinlima commented 6 years ago

Hi @PeachScript, I'm facing the same problem, 2 same requests at the same page, on first load of infinite-loading and only when request status return 304 (not modified), I already updated to v2.4.1.

First load: same_request

At this component I'm using the default structure:

infiniteHandler($state) {
  axios.get(api, {
    headers: {
      'Accept' : 'application/json'
    },
    params: {
      page: this.page,
    },
  }).then(({ data }) => {
  if (data.length > 0) {
      this.page += 1;
      this.list.push(...data);
      $state.loaded();
    } else {
      $state.complete();
    }
  })
}

I can give more details if you need :)

PeachScript commented 6 years ago

@lucassonsinlima is your problem caused by $state.reset()?

lucassonsinlima commented 6 years ago

@lucassonsinlima is your problem caused by $state.reset()?

Noup, I thought in opening another issue to my problem but this is quite similar due to the double requests at loading. Do you prefer that I open another one with my infos? Thanks :)

PeachScript commented 6 years ago

@lucassonsinlima that's great! Don't forget to provide a reproduce link in the new issue :P

denglai commented 6 years ago

Two tab tags, one use vue-infinite-loading, the other isn‘t use。the component of not using vue-infinite-loading plugin slides to the bottom, then switch tab to the component of using vue-infinite-loading, there will be double request at loading with the same data

PeachScript commented 6 years ago

@denglai please provide a reproduce link, thanks.

cwilby commented 4 years ago

Just dropping a note here, one workaround I have for this is to only add new elements by changing this.tasks.push(...data) to:

this.list = [
  ...this.list,
  ...data.filter(item => this.list.all(i => i.id !== item.id))
];