本文主要是介绍前端异步请求中后发先到的解决方案,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
通用的组件请求管理器,解决异步请求中的后发先到的问题
测试方法:可以使用fiddler进行测试,选择fiddler rules菜单中的automatic breakpoints中的afterResponse,这样可以阻止后端过快地返回,从而可以自己选择哪个请求的结果先返回,实现模拟后发先到的情况。
tips:每当需要取消之前发出的请求时,需要调用clearRequestId方法。
CommonRequestIdManager.js
/*通过id来跟踪请求和判断返回是否有效
*/
function CommonRequestIdManager() {if (!(this instanceof CommonRequestIdManager)) {return new CommonRequestIdManager();}this.initRequestId();}CommonRequestIdManager.prototype = {// id初始化initRequestId: function() {this.requestId = 0;},// 获取该次请求对应的idgetRequestId: function() {return this.requestId;},// 清除请求的id,把id加一,导致前面发出的请求不可用clearRequestId: function() {return this.addRequestId();},addRequestId: function() {return this.requestId++;},// 获取当前的请求idgetCurrentRequestId: function() {return this.getRequestId();},// 获取该次请求对应的回调getCb: function(cb,context) {var self = this;var requestId = this.getRequestId()console.log(requestId)return function(data) {// 对于返回的结果,判断回调函数绑定的id是否等于当前的请求idif (requestId === self.getCurrentRequestId()) {cb && cb.call(context || null, data);}}}}
测试页面
<!DOCTYPE html>
<html>
<head><title>my login</title><script type="text/javascript" src="jquery-1.10.2.js"></script>
</head>
<script type="text/javascript" src="./CommonRequestIdManager.js"></script>
<body><input type="text" name="name">submit<script type="text/javascript">var commonRequestIdManager = new CommonRequestIdManager();$('input').on('keydown', function() {// 清除前面发出的所有请求commonRequestIdManager.clearRequestId();$.ajax({url: '1.php',success:commonRequestIdManager.getCb(function() {console.log('success')}),error:commonRequestIdManager.getCb(function() {console.log('error')})})})</script>
</body></html>
优化版本:
/*通过id来跟踪请求和判断返回是否有效
*/
function CommonRequestIdManager() {if (!(this instanceof CommonRequestIdManager)) {return new CommonRequestIdManager();}// 是否已經取消了請求,如果是,則新建請求之前不需要再自增requestIdthis.hasCanceled = false;// 是否已經發送過請求this.haveEverMakeRequest = false;this.initRequestId();}CommonRequestIdManager.prototype = {// id初始化initRequestId: function() {this.requestId = 1;},// 获取该次请求对应的idgetRequestId: function() {return this.requestId;},// 清除请求的id,把id加一,导致前面发出的请求不可用,用於沒有發送新請求,但是通過其他操作取消了請求,比如點擊取消按鈕clearFormerRequest: function() {this.hasCanceled = true;this.addRequestId(); },/* 清除请求的id,把id加一,导致前面发出的请求不可用,用於發送新請求之前使用,如果已經通過其他操作取消了請求,或者還沒有發送過請求,則不需要再自增requestId。*/clearFormerRequestBeforeRequest: function() {if (!!this.hasCanceled || !this.haveEverMakeRequest) {return;}return this.addRequestId(); },addRequestId: function() {return this.requestId++;},// 获取当前的请求idgetCurrentRequestId: function() {return this.getRequestId();},// 获取该次请求对应的回调getCb: function(cb,context) {var self = this;var requestId = this.getRequestId();// 每次新發送請求之前重置標記位this.hasCanceled = false;this.haveEverMakeRequest = true;console.log(requestId)return function(data) {// 对于返回的结果,判断回调函数绑定的id是否等于当前的请求idif (requestId === self.getCurrentRequestId()) {cb && cb.call(context || null, data);}}}}
在优化版本中,显式定义了两种取消请求的方法,clearFormerRequest和clearFormerRequestBeforeRequest,后者用于在发送新的请求前使用,前者是没有发送新的请求,而是通过其他操作取消了请求,比如点击取消按钮。
这篇关于前端异步请求中后发先到的解决方案的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!