用于忽略先前请求响应的前端 JavaScript 模式

Front-end JavaScript pattern to ignore previous request responses

本文关键字:前端 JavaScript 模式 响应 请求 用于      更新时间:2023-09-26

我不是前端开发人员 - 用户可能会单击提交按钮来提交 AJAX 请求(这是一个 SPA),如果用户想尝试不同的设置,可能会在几秒钟后再次单击该按钮。我可以添加一个覆盖层并阻止他们提交,直到回复回来。但是,假设我不想使用覆盖方法 - 是否有一些编程模式可供我使用(也许是闭包?)来忽略除最新请求的响应之外的所有响应?

下面是一些代码作为示例:

define([
        '+appState',
        '#allModels',
        '#allCollections',
        'form2js',
        'ejs',
        'underscore',
        'react',
        '#allFluxActions'
    ],
    function (appState, models, collections, form2js, EJS, _, React, allFluxActions) {
        var actions = allFluxActions['FileAction'];
        var UploadFileView = React.createClass({

            handleSubmit: function (e) {
                e.preventDefault();
                this.props.clearUploadResult();
                var data = new FormData();
                data.append('file-0', this.state.file);

                if (!this.props.mappingType) {
                    alert('undefined mapping type.');
                    return;
                }
                else {
                    console.log('mapping type selected:', this.props.mappingType);
                }
                this.props.setStatus('PENDING');
                const self = this;
                return $.ajax({
                    type: 'POST',
                    url: 'http://172.x0.x.x1:4000/upload',
                    data: data,
                    headers: {
                        'x-baymax-mapping-type': this.props.mappingType
                    },
                    cache: false,
                    contentType: false,
                    processData: false
                }).done(function (resp) {
                    console.log(resp);
                    if (resp && resp.responseJSON && resp.responseJSON.success) {
                        self.props.setUploadResult('No upload errors, all clear.');
                    }
                    else if (resp && resp.responseJSON && resp.responseJSON.error) {
                        self.props.setUploadResult(resp.responseJSON.error);
                    }
                    else {
                        self.props.setUploadResult(resp);
                    }
                }).fail(function (resp) {
                    if (resp && resp.responseJSON && resp.responseJSON.error) {
                        self.props.setUploadResult(resp.responseJSON.error);
                    }
                    else {
                        self.props.setUploadResult('Fail - unexpected server error.');
                    }
                });
            },
            handleImageChange: function (e) {
                e.preventDefault();
                this.props.clearUploadResult();
                var reader = new FileReader();
                var file = e.target.files[0];
                var fileName = document.getElementById('fileName');
                fileName.innerHTML = file.name;
                console.log('File Data:', file);
                reader.onloadend = () => {
                    this.setState({
                        file: file
                    });
                };
                reader.readAsDataURL(file);
            },
            render: function () {
                return (
                    <div className='row fileUploadForm'>
                        <form onSubmit={this.handleSubmit}>
                            <div className='nine columns'>
                                <label className='fileUpload'>File Upload
                                    <input type='file' name='file' id='fileUpload' onChange={this.handleImageChange}/>
                                </label>
                                <span id='fileName'></span>
                                <div id="upload-submit-button-div" className="upload-submit-button-div">
                                    <button className='button-primary fileFormSubmit' type='submit'
                                            onClick={this.handleSubmit} value='Submit'>Submit
                                    </button>
                                </div>
                            </div>
                        </form>
                    </div>
                )
            }
        });

        return UploadFileView;
    });

当用户单击提交(选择文件后)时,响应可能需要 5-10 秒。我们的测试工程师会不耐烦,在最后一个响应返回之前尝试其他一些文件。单击提交按钮后,如何忽略以前的响应?我在想某种使用闭包的时间戳技巧,但我不确定。有点难倒。

您可以存储 $.ajax 请求,然后在发送下一个请求之前中止 () 它。

...
let lastAjax = null;
...
var UploadFileView = React.createClass({
  handleSubmit: function (e) {
    ...  
    if (!!lastAjax) {
      lastAjax.abort();
    }
    lastAjax = $.ajax({
      ...
    });
    return lastAjax;
  },
  ...
})

你必须做4件事:

  • 选择文件时,这将触发文件输入的更改事件,中止所有挂起的请求
  • 提交时,将禁用的布尔属性添加到按钮(如有必要,稍后将其删除),这样就不会有重复的请求
  • 选择文件后,(重新)将事件处理程序(仅执行一次)附加到"提交"按钮并删除其禁用属性
  • 对于 UX,添加微调器/加载器
我知道

这真的很老,但是当我搜索这种技术时它就出现了。

我相信您可以将全局变量与本地副本进行比较,以查看响应是否"过时",并在响应时忽略它:

let counter = 0;
handleSubmit: function (e) {
        // ... your stuff ...
        let self = this;
        ++this.counter;
        let localcounter = counter;
        return $.ajax({
            type: 'POST',
            //... etc ...
        }).done(function (resp) {
            if (localcounter != self.counter) {
               // ignore stale response!
            } else {
               // process result
            }
        }).fail(function (resp) {
            if (localcounter != self.counter) {
               // ignore stale response!
            } else {
               // process failure
            }
        });
}