我使用vue-infinite-loader来显示用户并将它们加载到滚动中。此外,我还有一个按名称过滤的方法。
我遵循了https://peachscript.github.io/vue-infinite-loading/guide/use-with-filter-or-tabs.html给出的说明
下面是过滤器的HTML:
<input v-model="name" type="text" class="form-control" placeholder="Search by name" @input="changeName">下面是相关的vue方法:
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次,一次是使用M、Ma和Max。问题是,调用是并行的,这意味着从Max开始的用户也会匹配到从Ma和M开始。因此,我突然有了重复的用户名,而且用户名不是以Max开头,而是以Marjon开头,等等。
我实际上在changeName()内部设置了一个超时,以防止在每次击键时都调用HTTP:
changeName() {
clearTimeout(this.timeout);
this.timeout = setTimeout(function() { ...}, 200);
},然而,上面的理论问题仍然有可能在这里发生(如果击键和HTTPS调用都超过200ms)。
如果用户输入"Ma“,然后输入"Max”,则由"Ma“触发的axios调用将停止,并立即执行对"Max”的调用。
发布于 2021-08-19 12:50:43
要取消axios请求,可以使用canceltoken
请注意,当您调用infiniteHandler时,先前的任何请求都会被取消,并且当请求完成时,取消标记也会被删除
因此,除了这里的几行代码外,不需要额外的代码
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代码来取消之前的请求(出于其他目的),则可能仍然有用
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();
}
});
});
},发布于 2021-08-19 12:45:24
可以在一个axios请求开始使用axios的CancelToken之前取消另一个axios请求
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();
}
});(代码未经过测试,但给出了想法)
https://stackoverflow.com/questions/68848002
复制相似问题