js函数整合队列顺序执行插件
前言
函数队列循环执行
/**
*1.0.0.1版本
*/
var list=[];//存储函数
list.push(function(){
console.log(1);
});
list.push(function(){
console.log(2);
});
list.push(function(){
console.log(3);
});
for (var i=0;fn=list[i++];) {
fn();//执行
}
结果:1,2,3
这是最简单的方式,可以实现函数整合成一个队列,按照先进先出顺序执行。现在在仔细看发现,如果函数中有异步执行那函数执行就不能保证按照顺序执行,例如:
var list=[];//存储函数
list.push(function(){
console.log(1);
});
list.push(function(){
setTimeout(function() {
console.log(2);
}, 2000);
});
list.push(function(){
console.log(3);
});
for (var i=0;fn=list[i++];) {
fn();//执行
}
输出的结果肯定是 1,3,2
/**
*1.0.0.2版本
*/
var list=[];
list.push(function(){
console.log(1);
});
list.push(function(){
console.log(2);
});
list.push(function(){
console.log(3);
}); function start(list){
if(list.length){
list.shift()();
arguments.callee(list);
}
}
start(list);
这种方式可以等到执行完毕,清除list内部执行过后的函数。不影响下次push 执行。但是异步函数还是未解决。
/**
*1.0.0.3版本
*/
var list=[];//存储数组的集合
list.push(function(){
console.log(1);
});
list.push(function(callback){
//callback是代表这个函数是异步的函数
setTimeout(function() {
console.log(2);
callback();//执行完异步函数执行回调函数
}, 2000);
});
list.push(function(){
console.log(3);
}); function start(){
//判断数组的长度
if(list.length){
var fn=list.shift();//取出数组第一个函数
//判断函数是否带有参数
if(fn.length){
fn(start);//执行该函数,并且把 start本身传递进去。
}else{
fn();
start();
}
}
}
start();
此版本可以解决带有异步执行的函数按照刚开始push进去的顺序依次执行。
需要注意的是,如果函数是内部带有异步执行的函数,需要传递一个参数来告诉start。但是如果我们push进去的函数本身有好多个参数这需要怎么办呢!!接下来看另一版本。
/**
*1.0.0.4版本
*/
var list=[];//存储数组的集合
list.push(function(){
console.log(1);
});
list.push(function(callback){
setTimeout(function() {
console.log(2);
callback();
}, 2000);
});
list.push(function(){
console.log(3);
}); function start(){
//判断数组的长度
if(list.length){
var fn=list.shift();//取出数组第一个函数
//判断函数是否带有参数
if(fn.length && getfunarg(fn)[0]=='callback'){
fn(start);//执行该函数,并且把 start本身传递进去。
}else{
fn();
start();
}
}
}
start();
/**
* 查找函数参数名
* @fn {Function } 要查找的函数
* @return []返回参数数组
* */
function getfunarg(fn) {
var f = /^[\s\(]*function[^(]*\(\s*([^)]*?)\s*\)/.exec(fn.toString());
return f && f[1] ? f[1].split(/,\s*/) : [];
}
到现在为止,我们这几个函数基本已经满足我们的需求,但是push的时候,假设函数多个参数,我们还需进一步优化代码!为了把这个插件做的更好。我决定还是把callback放在最后,这样就能保证函数传递参数不受影响。
最终版本
/**
* 作者:小小坤
* 联系:java-script@qq.com
* 日期:2017-11-11
* 版本:1.0.0.4
* -----------使用说明----------
* 1、把所有函数【包含异步执行的函数】按照顺序依次 使用lk.push存入
* 2、带有参数的函数,一定要注意{最一个参数如果是callback}会被认为是 异步执行函数
* 3、异步执行的函数,需要把最一个参数设置为callback。并在函数执行完毕执行callback();函数保证按照顺序执行
*
* */
;! function() {
var list = [], //存储函数的列表
isFun = Object.prototype.toString; //用于验证是否是函数
/**
* 添加到列表中
* @fn {Function} 函数体
* */
function push(fn) {
isFun.call(fn) === "[object Function]" && list.push(fn);
};
/**
* 开始执行列表中的所有函数,
* 按照先进先出原则
*
* */
function star() {
if(list.length) {
var fn = list.shift(),//截取第一个函数
arry=getfunarg(fn),//获取这个函数的参数列表
_length=arry.length;//参数列表的长度
if(_length && arry[_length-1] === 'callback') {
if(_length===1){
fn(star);
}else{
arry.pop();//删除最后一个参数
arry.push(star);//把回调函数存入数组
fn.apply(this,arry);
}
} else {
fn.apply(this,arry);
star();
}
}
}
/**
* 查找函数参数名
* @fn {Function } 要查找的函数
* @return []返回参数数组
* */
function getfunarg(fn) {
var f = /^[\s\(]*function[^(]*\(\s*([^)]*?)\s*\)/.exec(fn.toString());
return f && f[1] ? f[1].split(/,\s*/) : [];
}
//挂在到Windows上。
window.lk = {
push: push,
start: star
}
}();
//使用测试
/**--------一条华丽的分割线--------**/
var a=100,
b=200,
d=300,
f=400; //定义函数 a2 ,此函数带有一个参数,被认为是异步函数
function a2(a,b,callback) {
console.time('2');
setTimeout(function() {
console.timeEnd('2');
callback();
console.log(a,'a');
}, 1000);
}
//把函数函数 a2 放入数组
lk.push(a2); //定义函数 a3
function a3(d, f) {
console.log(f,'f');
console.log(3);
}
//把函数函数 a3 放入数组
lk.push(a3); //定义函数 a4 此函数带有一个参数,被认为是异步函数
function a4(callback) {
console.time('4');
setTimeout(function() {
console.timeEnd('4');
callback();
}, 2000);
}
//把函数函数 a4 放入数组
lk.push(a4); //最后开始执行
lk.start();
最终此插件完成,需要压缩的同学可以自行压缩。代码比较简单,提供了两个方法。
push存储函数列表
start开始执行
总结
通过上边的代码编写我们学到了处理函数列表时候,需要考虑到异步函数。处理异步函数,需要回调函数参与。这样就能帮助代码按照顺序执行。
js函数整合队列顺序执行插件的更多相关文章
- js函数和变量的执行顺序【易错】
js函数和变量的声明与执行顺序 一.函数执行顺序 1.正常顺序 function f(){ alert(2); } f(); //alert 2 所有浏览器都能测试通过. 2.倒序调用 f(); // ...
- 【原创】cs+html+js+css模式(七): 顺序执行与并发执行问题,IIS7及其以上版本的抛错问题解决
在进行开发的过程中,针对于这种模式,我们继承的IRequiresSessionState,这种对于我们的同一个IIS的执行中是顺序执行即一个ajax请求处理完成后,才能执行下一个ajax, ...
- js函数的解析与执行过程
function f(a,b,c){ alert(a);//函数字符串 alert(b); var b = 5; function a(){ } } f(1,2); //预处理 lexicalEnvi ...
- 在JS函数中执行C#中的函数、字段
1.调用字段 cs文件的代码: ; protected void Page_Load(object sender, EventArgs e) { id = ; } js页面的代码: function ...
- 各种常用js函数实现
1.bind function bind(fn, context) { var args = Array.prototype.slice.call(arguments, 2); retur ...
- 如何编写高质量的 JS 函数(1) -- 敲山震虎篇
本文首发于 vivo互联网技术 微信公众号 链接:https://mp.weixin.qq.com/s/7lCK9cHmunvYlbm7Xi7JxQ作者:杨昆 一千个读者,有一千个哈姆雷特. 此系列文 ...
- jquery和js的几种页面加载函数的方法以及执行顺序
参考博客:http://www.cnblogs.com/itslives-com/p/4646790.html https://www.cnblogs.com/james641/p/783837 ...
- js函数和变量的声明与执行顺序
一.函数执行顺序 1.正常顺序 function f(){ alert(2); } f(); //alert 2 所有浏览器都能测试通过. 2.倒序调用 f(); //alert 2 function ...
- js的并行加载以及顺序执行
重新温习了下这段内容,发现各个浏览器的兼容性真的是搞大了头,处理起来很是麻烦. 现在现总结下并行加载多个js的方法: 1,对于动态createElement('script')的方式,对所有浏览器都是 ...
随机推荐
- Java高新技术 反射机制
Java高新技术 反射机制 知识概要: (1)反射的基石 (2)反射 (3)Constructor类 (4)Field类 (5)Method类 (6)用反射方 ...
- codesmith连接Mysql提示“找不到请求的 .Net Framework Data Provider。可能没有安装。"
1,首先需要将MySql.Data.dll复制到codesmith安装目录下bin文件夹下,注意dll的版本 2,其次因为codesmith7采用的是.net4.0的配置文件,(64位系统)找到C:\ ...
- BZOJ-4915-简单的数字题
Description 对任意的四个不同的正整数组成的集合A={a_1,a_2,a_3,a_4 },记S_A=a_1+a_2+a_3+a_4,设n_A是满足a_i+a_j (1 ≤i<j≤4)| ...
- 小白学Maven第二篇配置Ecilpse
Maven:里面提到了一个很重要的概念:中央仓库,本地仓库,私服: 中央仓库:是Maven通过一个地址索引去(http://mvnrepository.com/)下载需要的架包: 本地仓库:是Mave ...
- JAVA基础总结2
2.1 关键字 常用的关键字主要包括如下: 2.2 标识符 简单而言标识符它其实就是用于标识某些东西的符号. 2.3 注释的应用 注释说明 注释的作用: 注释的应用: 2.4 常量和变量 常量的定义与 ...
- 【转载】quickLayout.css-快速构建结构兼容的web页面
文章转载自 张鑫旭-鑫空间-鑫生活 http://www.zhangxinxu.com/wordpress/ 原文链接:http://www.zhangxinxu.com/wordpress/?p=4 ...
- ASP.NET Core 网站发布到Linux服务器(转)
出处;ASP.NET Core 网站发布到Linux服务器 长期以来,使用.NET开发的应用只能运行在Windows平台上面,而目前国内蓬勃发展的互联网公司由于成本的考虑,大量使用免费的Linux平台 ...
- java遍历hashMap、hashSet、Hashtable
一.遍历HashMap Map<Integer, String> map = new HashMap<Integer, String>(); 方法一:效率高 for(Entry ...
- 【转】S3C2440与SDRAM NorFlash NandFlash连线分析
一.SDRAM(HY57V561620F)连线分析 1. S3C2440 有27根地址线ADDR[26:0],8根片选信号ngcs0-ngcs7,对应bank0-bank7,当访问bankx 的地址 ...
- Java 获取SQL查询语句结果
step1:构造连接Class.forName("com.mysql.jdbc.Driver"); Connection con = DriverManager.getConnec ...