首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >无限加载器和筛选器上的重复条目

无限加载器和筛选器上的重复条目
EN

Stack Overflow用户
提问于 2021-08-19 12:34:53
回答 2查看 42关注 0票数 0

我使用vue-infinite-loader来显示用户并将它们加载到滚动中。此外,我还有一个按名称过滤的方法。

我遵循了https://peachscript.github.io/vue-infinite-loading/guide/use-with-filter-or-tabs.html给出的说明

下面是过滤器的HTML:

代码语言:javascript
复制
 <input v-model="name" type="text" class="form-control" placeholder="Search by name" @input="changeName">

下面是相关的vue方法:

代码语言:javascript
复制
 methods: {
        infiniteHandler: function ($state) {
            console.log(api + this.parameter);
            axios.get(api + this.parameter, {params: {page: this.page}}).then((result) =>   {
                if (result.data.meta.current_page <= result.data.meta.last_page) {
                    this.page += 1;
                    this.users.push(...result.data.data);

                    $state.loaded();
                } else {
                    $state.complete();
                }
            });
        },
        changeName() {
             this.parameter= '?name=' + encodeURIComponent(this.name);
             this.page = 1;
             this.users = [];
             this.infiniteId += 1;                          
        },

如果我现在在输入文本字段中快速输入"Max“作为用户名,那么changeName将被执行3次,一次是使用MMaMax。问题是,调用是并行的,这意味着从Max开始的用户也会匹配到从MaM开始。因此,我突然有了重复的用户名,而且用户名不是以Max开头,而是以Marjon开头,等等。

我实际上在changeName()内部设置了一个超时,以防止在每次击键时都调用HTTP:

代码语言:javascript
复制
 changeName() {            
     clearTimeout(this.timeout);
     this.timeout = setTimeout(function() { ...}, 200);
 },

然而,上面的理论问题仍然有可能在这里发生(如果击键和HTTPS调用都超过200ms)。

如果用户输入"Ma“,然后输入"Max”,则由"Ma“触发的axios调用将停止,并立即执行对"Max”的调用。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2021-08-19 12:50:43

要取消axios请求,可以使用canceltoken

请注意,当您调用infiniteHandler时,先前的任何请求都会被取消,并且当请求完成时,取消标记也会被删除

因此,除了这里的几行代码外,不需要额外的代码

代码语言:javascript
复制
methods: {
    infiniteHandler: function ($state) {
        console.log(api + this.parameter);
        // _cancelSource is truthy if there's a request "in flight"
        if (this._cancelSource) {
            this._cancelSource.cancel('new search');
            this._cancelSource = null;
        }
        // get a new canceToken
        this._cancelSource = axios.CancelToken.source();
        axios.get(api + this.parameter, {
            cancelToken: this._cancelSource.token
            params: {page: this.page}
        }).then((result) =>   {
            // no need to cancel now
            this._cancelSource = null;
            if (result.data.meta.current_page <= result.data.meta.last_page) {
                this.page += 1;
                this.users.push(...result.data.data);
                $state.loaded();
            } else {
                $state.complete();
            }
        });
    },

如果取消不是很有效,您可以链接由axios返回的承诺。

然而,我不认为这是必需的

如果您不想通过删除cancelToken代码来取消之前的请求(出于其他目的),则可能仍然有用

代码语言:javascript
复制
methods: {
    infiniteHandler: function ($state) {
        console.log(api + this.parameter);
        
        // initialise the promise for first time
        this._requestPromise = this._requestPromise || Promise.resolve();
        
        // _cancelSource is truthy if there's a request "in flight"
        if (this._cancelSource) {
            this._cancelSource.cancel('new search');
            this._cancelSource = null;
        }
        // get a new canceToken
        this._cancelSource = axios.CancelToken.source();
        
        // chain on to the previous request
        // NOTE: cancelling the previous request will make it reject ... 
        //      but that can be handled
        this._requestPromise = this._requestPromise
         // handle any cancelled previous request
         // or previous request rejections
         // we still want to do this one if the previous rejected
        .catch(() => {}) 
        .then(() => {
            axios.get(api + this.parameter, {
                cancelToken: this._cancelSource.token
                params: {page: this.page}
            }).then((result) =>   {
                // no need to cancel now
                this._cancelSource = null;
                if (result.data.meta.current_page <= result.data.meta.last_page) {
                    this.page += 1;
                    this.users.push(...result.data.data);
                    $state.loaded();
                } else {
                    $state.complete();
                }
            });
        });
    },
票数 1
EN

Stack Overflow用户

发布于 2021-08-19 12:45:24

可以在一个axios请求开始使用axios的CancelToken之前取消另一个axios请求

代码语言:javascript
复制
const CancelToken = axios.CancelToken;
const source = CancelToken.source();

axios.get(api + this.parameter, {
    params: {page: this.page}},
    cancelToken: source.token
).then((result) =>   {
    if (result.data.meta.current_page <= result.data.meta.last_page) {
        this.page += 1;
        this.users.push(...result.data.data);
        $state.loaded();
    } else {
        $state.complete();
    }
});

(代码未经过测试,但给出了想法)

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/68848002

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档