I'm working on a type ahead input component and part of my implementation is a queue or buffer FIFO of cancelable promises.
Because the typing can happen much faster than the async requests on each letter, I have to cancel the previous request, so that state is not inadvertently changed if the previous promise is slower than the current.
My current implementation works well, but I'm wondering if its necessary to maintain a queue vs. a single reference. The queue should never really grow to retain more than one promise at a time, right?
_onChangeEvent(str) {
var self = this;
var str = String(str) || '';
var toBeCanceled = null;
// set state return false if no str
// and shift off last request
if (!str) {
if (this.requestQueue.length > 0) {
toBeCanceled = this.requestQueue.shift();
toBeCanceled.cancel();
}
this.setState({results: [], loading: false, value: ''});
return false;
} else {
this.setState({loading: true, value: str});
}
// setup a cancelable promise and add it to the queue
// this API spoofer should eventually be a dispatch prop
var cancelable = CancelablePromise(APISpoofer(str));
cancelable
.promise
.then((res) => {
var sorted = res.found.sort((a, b) => {
var nameA = a.toLowerCase(), nameB = b.toLowerCase();
if(nameA < nameB) return -1;
if(nameA > nameB) return 1;
return 0;
}).slice(0, 4);
// set state and shift queue when resolved
return self.setState({
results: sorted,
loading: false,
value: str
}, () => {
self.requestQueue.shift();
});
})
.catch((err) => {
return err;
});
// check len of requestQueue and push
if(this.requestQueue.length === 0) {
this.requestQueue.push(cancelable);
} else {
// cancel previous and push
toBeCanceled = this.requestQueue.shift();
toBeCanceled.cancel();
this.requestQueue.push(cancelable);
}
}
Is there a problem with maintaining a queue of one value? Also, is there a name for this kind of problem?