admin管理员组文章数量:1296485
If I get enough users on my application, sending an ajax request with each keystroke is an effective way to bring the server to its knees (not to mention possibly making the client application feel quite sluggish). On implementing a symbol search box with two options (DB Search and Web Api Search). While I am typing the symbol (ex: AAPL - aple stock) in the search box the fetch()
request is sent each time over the network. To avoid it I tried to use setTimeout()
but fetch()
request is sent multiple times, anyway. How to delay/start/debounce fetching the request until user stops typing in input area to send only one fetch()
request?
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').autoplete({
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
}
Here is the console result:
Here is the network result:
If I get enough users on my application, sending an ajax request with each keystroke is an effective way to bring the server to its knees (not to mention possibly making the client application feel quite sluggish). On implementing a symbol search box with two options (DB Search and Web Api Search). While I am typing the symbol (ex: AAPL - aple stock) in the search box the fetch()
request is sent each time over the network. To avoid it I tried to use setTimeout()
but fetch()
request is sent multiple times, anyway. How to delay/start/debounce fetching the request until user stops typing in input area to send only one fetch()
request?
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').autoplete({
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
}
Here is the console result:
Here is the network result:
Share Improve this question edited Jan 22, 2019 at 5:29 John John asked Jan 22, 2019 at 4:02 John JohnJohn John 1,5004 gold badges22 silver badges45 bronze badges 2-
how about using minimum input length, For example
fetch
request will be made only after n number of characters entered in the input – brk Commented Jan 22, 2019 at 4:05 - @brk the problem that it could be one letter symbol as well – John John Commented Jan 22, 2019 at 4:06
1 Answer
Reset to default 9This is monly solved by debouncing the event; which collapses multiple calls in a given timeframe to just one:
// Debounce function from: https://stackoverflow./q/24004791/1814486
const debounce = (func, wait, immediate) => {
let timeout
return function() {
const context = this, args = arguments
const later = function() {
timeout = null
if (!immediate) func.apply(context, args)
}
const callNow = immediate && !timeout
clearTimeout(timeout)
timeout = setTimeout(later, wait)
if (callNow) func.apply(context, args)
}
}
// If there's not another `input` within 500ms log the value,
// otherwise ignore the event.
document.querySelector('#input').addEventListener('input', debounce(() => {
console.log(input.value)
}, 500))
<input id="input" placeholder="Type fast here.."/>
本文标签: javascriptHow to delaystartdebounce fetching data until user stops typingStack Overflow
版权声明:本文标题:javascript - How to delaystartdebounce fetching data until user stops typing? - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1741624455a2389001.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论