- /**
- *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开始执行
通过上边的代码编写我们学到了处理函数列表时候,需要考虑到异步函数。处理异步函数,需要回调函数参与。这样就能帮助代码按照顺序执行。
来源: http://www.cnblogs.com/xiaoxiaokun/p/7838377.html