异步类型提前输入缓冲区或队列 [英] Async type ahead input buffer or queue

查看:95
本文介绍了异步类型提前输入缓冲区或队列的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在处理类型提前输入组件,实现的一部分是可取消承诺的队列或缓冲区FIFO.

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?

推荐答案

由于您的代码会在发送新请求之前立即取消任何进行中的请求,因此您的队列将永远不会包含一个以上的元素.因此,使用队列毫无用处,简单的 currentRequest 字段足以确保您只能处理最新请求,而不管其处理顺序如何.

As your code immediately cancels any in-flight request before sending a new one, your queue will never contain more than one element. So it's useless to use a queue, a simple currentRequest field is enough to ensure you can handle only the most recent request, no matter in what order they are processed.

提前输入控件的常见做法是限制输入事件,即在实际发送AJAX请求之前,等待一小段时间进行另一项更改.这样可以避免在用户快速键入多个字母时发送太多请求.

A common practice in type-ahead controls is to throttle the input events, i.e. wait a short amount of time for another change before actually sending an AJAX request. This avoids sending too many requests when users type several letters in a quick fashion.

如果您愿意使用反应式编程技术(例如,使用RxJS http://reactivex.io/.

Both of those problems can be abstracted from your code if you are willing to use reactive programming techniques, e.g. using RxJS http://reactivex.io/.

实际上,在以下RxJS页面的某个地方,您会找到一个完全做到这一点的示例:观察输入更改,至少需要2个字符,反跳,查询Web服务,然后处理结果:

In fact somewhere down on the following RxJS page you will find an example that does exactly that: observing input changes, requiring at least 2 chars, debouncing, querying a webservice and then handling the results: https://github.com/Reactive-Extensions/RxJS

这篇关于异步类型提前输入缓冲区或队列的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆