文档章节

js异步ajax方法实现顺序执行(通过轮询方式)

社哥
 社哥
发布于 2017/12/07 11:38
字数 849
阅读 528
收藏 19

1.问题描述

在使用ajax传送数据时总会遇到一个问题,即ajax顺序传输数据.

传统方法,一般是将ajax传递数据的async设为false,转为同步传输,一般可以保证对应的方法能按照上下文的顺序依次执行,对于网速较快且数据量较小的情况下,这么做完全没有问题.

但经常会遇到一种情况,数据量很大,或者在服务器后台的运算读取时间很长,导致ajax从发送到接收请求中间的经过时间较长(譬如1S以上,这个也受网速的影响),此时如果再设定为同步,用户就会感觉网页打开很卡(实际此时主页面可能已经加载完毕),带来很不好的用户体验.

此时就还是应当考虑使用异步ajax传输数据,所要解决的问题,就是如何保证异步ajax方法按照顺序执行.


2.解决思路

本文所描述解决策略,是利用setInternal()轮询函数.所有前置函数在ajax接收成功后设定一个标志位状态,setInternal中的函数参数将会轮询这些标志位状态,当确定状态为已完成状态之后,将会执行后行函数,以此类推.当所有后行参数执行完后,再销毁这个轮询函数.


3.演示代码

本代码中通过延时函数模拟ajax操作,以此方便大家测试.实际在使用ajax作为前置及后行函数时,该思路是完全没有问题的.
此代码的流程是:

  1. 先执行func3,func5;
  2. 待这两个前置函数执行完毕后再执行func4;
  3. 待func4执行完毕后,再执行func6.
//开始测试函数,可将此函数通过事件触发(如页面载入事件)
function test_(){		
	func3();
	func5();
	window.mAjaxFuncFlag=new Object();
	var mSiFunc4=setInterval(function(){
		if(window.mAjaxFuncFlag.func3&&window.mAjaxFuncFlag.func5){
			func4();
			clearInterval(mSiFunc4);
		}
	},100);//此处是当func3,func5执行完毕后,执行func4
	var mSiFunc6=setInterval(function(){
		if(window.mAjaxFuncFlag.func4){
			func6();
			clearInterval(mSiFunc6);
		}
	},100);//此处是当func4执行完毕后,执行func6
}
//模拟ajax函数3
function func3(){
	setTimeout(function(){
		showNowSec();
		window.mAjaxFuncFlag.func3=true;
	},3000);
}
//模拟ajax函数4
function func4(){
	setTimeout(function(){
		showNowSec();
		window.mAjaxFuncFlag.func4=true;
	},4000);
}
//模拟ajax函数5
function func5(){
	setTimeout(function(){
		showNowSec();
		window.mAjaxFuncFlag.func5=true;
	},5000);
}
//模拟ajax函数6
function func6(){
	setTimeout(function(){
		showNowSec();
		window.mAjaxFuncFlag.func6=true;
	},5000);
}
//打印当前秒数
function showNowSec(){
	console.log(new Date().getSeconds());
}

4.待改进的地方

目前该策略能很好的解决一些比较简单的异步ajax顺序执行问题,但也存在着一些不足,列举如下(也许以后姿势水平高了之后可以找到更好的方案):

  1. 对于函数代码的侵入性较高.每个函数内部都有一个记录函数真正完成(对于ajax即是数据传输完毕)的标志位设置(如果已将ajax封装,可考虑在complete中加入标志位设置的代码,以此减少侵入性);
  2. 当方法数量较多时,轮询部分的代码将会比较复杂.此处可以考虑写封装函数.但以何种形式的参数引入,同样也是个有争议的问题,在没有比较好的方案确定下来之前就先不将代码放上来了.

© 著作权归作者所有

共有 人打赏支持
社哥
粉丝 9
博文 15
码字总数 34261
作品 0
石家庄
程序员
私信 提问
加载中

评论(8)

l
lanny-fighting

引用来自“张亦俊”的评论

Promise欢迎你
而且有fetch这种现代化的东西,不用考虑兼容性问题的话,谁去折腾这个。

引用来自“杨意社”的评论

嗯,不了解这个东西,有时间我了解下.
‘’‘’哦哦哦哦哦哦哦哦哦哦哦哦哦哦哦
社哥
社哥

引用来自“梦天126”的评论

前段时间用node的时候碰到过异步的问题,当时直接用的最暴力的success后面执行来解决的
主要是前不久遇到一种情况,
有三个ajax:A,B,C传输要完成,
其中C必须要A,B同时传输成功后才能发送,
这时候用这种success后接的方法,就有些问题了.
社哥
社哥

引用来自“梦天126”的评论

前段时间用node的时候碰到过异步的问题,当时直接用的最暴力的success后面执行来解决的
我最开始的时候也是用这种方式,用于比较简单的情况完全没有太大问题.
梦天126
前段时间用node的时候碰到过异步的问题,当时直接用的最暴力的success后面执行来解决的
社哥
社哥

引用来自“张亦俊”的评论

Promise欢迎你
而且有fetch这种现代化的东西,不用考虑兼容性问题的话,谁去折腾这个。
嗯,不了解这个东西,有时间我了解下.
社哥
社哥

引用来自“陈狐”的评论

LZ这个思路我看懂了,就是说把不同的ajax方法分批执行,前面的没执行成功就不会去执行后面的。但是我有个疑问,不同的ajax方法之间会互相影响吗?(难道一个ajax方法没有成功,其他的ajax全部失效吗?)
关于ajax之间的相互影响,大致有两种情况:
1.只有成功之后才能进行下面方法的执行.这种情况放到success后调用的方法即可.
2.无论成功与否,都需要进行下面的方法.即会出现你说的情况,放到complete后调用的方法即可.这样规定的ajax方法返回错误之后,还是会往下走.
正因为两种情况可能都需要考虑,代码侵入性强这点使得封装更加困难,只能说灵活性与方便性难以取舍.
张亦俊
张亦俊
Promise欢迎你
而且有fetch这种现代化的东西,不用考虑兼容性问题的话,谁去折腾这个。
陈狐
陈狐
LZ这个思路我看懂了,就是说把不同的ajax方法分批执行,前面的没执行成功就不会去执行后面的。但是我有个疑问,不同的ajax方法之间会互相影响吗?(难道一个ajax方法没有成功,其他的ajax全部失效吗?)
Javascript 异步实现机制

Javascript 单线程指的是在一个浏览器进程中只存在一个 Javascript 执行线程,所以任务需要顺序排列等待执行,而不能像 Java 等多线程语言一样并发执行。但是这种单线程模型在处理耗时的异步...

木头先生
2017/12/11
0
0
Javascript是单线程的深入分析

面试的时候发现99%的童鞋不理解为什么JavaScript是单线程的却能让AJAX异步发送和回调请求,还有setTimeout也看起来像是多线程的?还有non-blocking IO, event loop等概念很不清楚。来深入分析...

stone_
2014/04/15
0
0
Q:你了解异步编程、进程、单线程、多线程吗?

相关定义 Javascript语言将任务的执行模式分成两种:同步(Synchronous)和异步(Asynchronous)。 同步:一个进程在执行某个请求的时候,若该请求需要一段时间才能返回信息,那么这个进程将...

Juicyangxj
2017/11/28
0
0
JavaScript异步精讲,让你更加明白Js的执行流程!

JavaScript异步精讲,让你更加明白Js的执行流程! 问题点 什么是单线程,和异步有什么关系 什么是 event-loop jQuery的Deferred Promise 的基本使用和原理 async/await(和 Promise的区别、联...

推荐码发放
05/28
0
0
webqq更新——采用反向AJAX实现在线人员上下线模拟

原文: http://www.abigdreamer.com/mywork/webqq-update-online-reverse-ajax-implementation-off-the-assembly-line-simulation.html 本blog已转移到造梦师http://www.abigdreamer.com,欢......

暗之幻影
2015/09/23
0
0

没有更多内容

加载失败,请刷新页面

加载更多

Spirng事务简单入门

一、概述 spring支持编程式事务管理和声明式事务管理两种方式: 1.编程式事务管理使用TransactionTemplate或者直接使用底层的PlatformTransactionManager。对于编程式事务管理,spring推荐使...

嘴角轻扬30
13分钟前
2
0
独立IP被恶意绑定域名处理办法

80端口: listen 80 default_server; server_name _; return 444; 443端口: listen 443 ssl default_server; server_name _; 加上证书路径 return 444;...

会当凌绝顶
16分钟前
3
0
RabbitMQ+PHP 教程五(Topics)

开始 在前面的教程中,我们改进了日志系统。我们使用的是一种直接广播方式,而不是只使用一种直接(direct)广播方式的fanout交换机,从而获得了有选择地接收日志的可能性。 虽然使用直接direc...

hansonwong
23分钟前
1
0
未来Linux Kernel 将不支持可变长数组VLA

但使用 VLA 会存在问题,包括增加运行时开销——因为数组长度需要在运行时确定; LLVM Clang 编译器不支持结构内 VLA,它只支持 C99 风格的 VLA;存在安全隐患。Linus Torvalds 对 VLA 的使用...

linux-tao
25分钟前
2
0
给Jenkins增加Linux奴隶节点

Add linux slave node in the Jenkins https://mohitgoyal.co/2017/02/14/add-linux-slave-node-in-the-jenkins/ https://www.howtoforge.com/tutorial/ubuntu-jenkins-master-slave/ https:......

圣洁之子
26分钟前
2
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部