搜索书籍
来源:14-12 搜索实现4:动态绑定input输入

tom睡着了
2019-04-07
老师您好,最近又重新看了下这门课程的后几节,发现了一个小问题,以下是我对这个问题的描述和解决方案,不知道是否正确,望指教!
问题描述:
在网络速度不佳的时候,提交搜索后不能及时显示数据,此时点击取消并重新搜索另一个关键字,最终的结果是搜索两个关键字的并集。
问题重现:
先搜索韩寒,立刻点击取消再次搜索金庸,再次点击取消,最后再搜索王小波,出现的结果是三个关键字查询结果的并集。
问题分析:
我觉得出现这样的问题在于点击取消时,没有将已经发送的request请求关闭。虽然在代码中已经在每次搜索前清空dataArray,但是由于网络原因过慢,第一次的请求响应会在第三次发送请求后才会回来,所以第一、二、三次的查询结果都会被添加到dataArray中。
我的解决方案:
为promise对象再进行封装,使其能够具备取消功能。
关键代码:
// 在promise对象上进行封装,通过_hasCanceled变量标记其是否已经取消
const makeCancelable = function(promise){
let _hasCanceled = false
const wrappedPromise = new Promise((resolve, reject)=>{
promise.then((res)=>{
if(_hasCanceled){
// 已经取消,调用内部promise对象的reject方法
reject({isCanceled: true})
} else {
resolve(res)
}
})
promise.catch((err)=>{
if(_hasCanceled) {
reject({isCanceled: true})
} else {
resolve(err)
}
})
})
return {
promise: wrappedPromise,
cancel() {
_hasCanceled = true;
}
}
}
export{
makeCancelable
}
// BookModel.js
searchWithCancel(start, q) {
const promise = this.request({
url: 'book/search?summary=1',
data: {
q: q,
start: start
}
})
return makeCancelable(promise)
}
// search component js
data:{
// ...
// 添加一个data,用于触发cancel函数
searchWithCancel: null
},
onConfirm(event) {
// ...
const searchWithCancel = bookModel.searchWithCancel(0, word)
this.data.searchWithCancel = searchWithCancel
searchWithCancel.promise
.then(res => {
this.setMoreData(res.books)
this.setTotal(res.total)
keyworkModel.addToHistory(word)
this._hideLoadingCenter()
}).catch(err => {
console.log(err)
})
},
onCancelSearch() {
// 点击取消按钮
this.data.searchWithCancel.cancel()
this.initialize()
this.triggerEvent('cancelSearch', {}, {})
},
onClearResult() {
// 点击x图标
this.data.searchWithCancel.cancel()
this.initialize()
this._closeResult()
}
写回答
1回答
-
7七月
2019-04-07
这里是可能存在这个问题,所以在一次搜索后,需要禁止第二次搜索。也可以把搜索用 一个页面来做,就不会有这个问题。
032019-04-07
相似问题