4 ms·
Wait for User to Stop Typing, in JavaScript
- beaconstudios 7y agoit's much more scalable to write time-dependent code like this in a reactive stream library like RxJS or Bacon. Rx example: Rx.fromEvent(input, 'keyup') // stream of keyup events .pipe(map(e => e.target.value)) // map to stream of values .pipe(debounceTime(1000)) // debounce the stream .subscribe(value => console.log('text', value)); this scales linearly with the addition of time-dependent features - say you want to map that value stream into an API request ie a Promise, but you want to only have the latest Promise actually write to your output in case an earlier request took longer to complete and finished after the latest one. That goes like this: Rx.fromEvent(input, 'keyup') // stream of keyup events .pipe(map(e => e.target.value)) // map to stream of values .pipe(debounceTime(1000)) // debounce the stream .pipe(switchMap(value => axios.get(`${API}/endpoint`))) // switchMap is like a stream version of flatMap, but only uses the latest result .subscribe(response => setState({ results: response.data })); you can do things like that with plain JS, but it gets convoluted very quickly. you can do a lot of clever stuff with this stream manipulation. I've managed to build some complex pieces of drag and drop UI in a few lines of code using Rx and React.
- barnaclejive 7y agoWait for User to Stop Typing, in Rx.
- jamespetercook 7y agoThe immensely useful lodash library comes with a debounce utility you can use for this. https://lodash.com/docs/4.17.15#debounce https://lodash.com/docs/4.17.15#debounce import { debounce } from 'lodash'; input.addEventListener('keyup', debounce(handleInputChange, 1000));
- shireboy 7y agoI use this technique all the time. One caveat, though: if you're doing ajax calls inside that callback (ie for an autocomplete), you _also_ want to cancel those at the same time you clearTimeout(). Browsers only do so many XHR requests at a time, so depending on timing (how fast the typist is, how fast the request is, etc) , this can queue up lots of unnecessary requests if you don't also cancel previous requests..
- marshmellman 7y agoAnother reason to cancel pending requests is that there’s no guarantee on the order the responses will resolve. So the UI might display autocomplete results from an earlier user input.
- jamespetercook 7y agoGood point. Curious, does the server stop execution if you cancel a request? Or does the browser just discard the response when it receives it?
- marshmellman 7y agoI believe browsers will close the socket, not keep it open and then discard the response. Browsers certainly have no way to terminate server execution.
- shireboy 7y agoI was thinking that at first too, but the more I thought about it, maybe they do? For example if I GET /some/large/file.pdf, get 50% through, then cancel, the server is not going to _keep sending the bits_, is it? It should handle the socket closed stop reading the file, etc. With sever code, I've never seen IIS cancel ASP.NET code, but now I'm wondering if it doesn't make sense in some cases... Actually, yeah, you can do it in ASP.NET, looks like: https://andrewlock.net/using-cancellationtokens-in-asp-net-core-mvc-controllers/ https://andrewlock.net/using-cancellationtokens-in-asp-net-c...
- shireboy 7y agoI think in most cases in HTTP, the server does not "know" the browser has canceled and so continues to execute. I believe it builds the response but can no longer send it because the underlying TCP connection is closed. So server continues to execute, but response bits never make it back to the client computer. WebSockets and HTTP2 may change that story somewhat. Edit: actually, I think I'm wrong here. Server does get a canceled socket, and can pass that to server code. In ASP.NET Core, this: https://andrewlock.net/using-cancellationtokens-in-asp-net-core-mvc-controllers/ https://andrewlock.net/using-cancellationtokens-in-asp-net-c...