如果我的应用程序上有足够的用户,则每次击键发送ajax请求都是使服务器屈服的有效方法(更不用说可能会使客户端应用程序变得很迟钝了)。实现带有两个选项的符号搜索框(DB搜索和Web Api搜索)。当我在搜索框中输入符号(例如:AAPL-大量股票)时,每次通过网络发送fetch()
请求。为了避免这种情况,我尝试使用setTimeout()
,但是无论如何都多次发送fetch()
请求。如何在用户停止输入区域以仅发送一个fetch()
请求之前,延迟/开始/反跳获取请求?
HTML:
<label for="symbolTags">Symbol: </label>
<input type="text" id="symbolTags" name="symbol">
<label for="api">Select Search Api: </label>
<select id="api" name="routes_api">
<option value="search">Web Search Api</option>
<option value="dbsearch">DB Search Api</option>
</select>
JavaScript:
const symbolTags = document.querySelector('#symbolTags')
const symbolTagsOptions = document.querySelector('#api')
const urlsObject = {
dbsearch: '/dbsearch/',
search: '/search/'
}
symbolTags.oninput = function () {
let symbolTagsOptionsValue = symbolTagsOptions.value
let arg = urlsObject[symbolTagsOptionsValue]
// Init a timeout variable to be used below
let timeout = null
// Clear the timeout if it has already been set.
// This will prevent the previous task from executing
// if it has been less than <MILLISECONDS>
clearTimeout(timeout)
// Make a new timeout set to go off in 2000ms
timeout = setTimeout(function () {
requestSymbolSearch(arg)
}, 2000)
}
function requestSymbolSearch(arg) {
getData(arg)
.then(data => {
console.log(data)
$('#symbolTags').autocomplete({
source: data.map(item => item.symbol),
autoFocus: true
})
})
.catch(error => console.error('Error:', error))
}
function getData(url) {
let curValueSymbol = symbolTags.value
let urlPlus = `${url}${curValueSymbol}`
console.log(urlPlus)
return fetchData(urlPlus)
}
async function fetchData(urlPlus) {
const dataResponse = await fetch(urlPlus)
const dataJson = await dataResponse.json()
return dataJson
}
这是控制台结果:
以下是网络结果:
答案 0 :(得分:1)
通常通过事件 debouncing 解决此问题:
// Debounce function taken from: https://stackoverflow.com/q/24004791/1814486
function debounce(func, wait, immediate) {
var timeout;
return function() {
var context = this, args = arguments;
var later = function() {
timeout = null;
if (!immediate) func.apply(context, args);
};
var callNow = immediate && !timeout;
clearTimeout(timeout);
timeout = setTimeout(later, wait);
if (callNow) func.apply(context, args);
};
};
const input = document.querySelector('#input')
// if there's not another `input` within 700ms, log the value,
// otherwise ignore the event.
input.addEventListener('input', debounce(() => {
console.log(input.value)
}, 700))
<input id="input" placeholder="Type here.."/>