js setTimeout深度递归后完成回调

setTimout原型:

iTimerID = window.setTimeout(vCode, iMilliSeconds [, sLanguage])
   
  setTimeout有两种形式

setTimeout(code,interval)
  setTimeout(func,interval,args)

var i=0;
   function test(){
       i+=1;
       alert(i);
   }
   setTimeout("test()",1000);
   也可以这样:
   setTimeout(test,1000);

问题:

因为递归太深而使用了异步的 setTimeout 清空调用栈,整个递归变成了异步的行为,函数已经提前返回了,现在怎么设置整个递归完成后的回调?

回答:

// 无回调
 function isArray(o) {
     return toString.apply(o) === ‘[object Array]‘;
 }
 function foo(arr) {
     console.log(arr);
     if (isArray(arr)) {
         for (i in arr) {
             (function(j) {
             setTimeout(function() {
                 foo(arr[j]);
             }, 0);
             })(i);
         }
     }
 }
 foo([[1, 2], [3, 4]]);

/*
 输出:
 [[1,2],[3,4]]
 [1,2]
 [3,4]
 1
 2
 3
 4
 */

 //有回调
 function isArray(o) {
     return toString.apply(o) === ‘[object Array]‘;
 }
 // 设置一个计数器,标识“已知的还未被遍历的元素数量”,起始值显然为1
 var cbCounter = 1;
 function foo(arr, cb) {
     cbCounter += isArray(arr) ? arr.length : 0; // 把子元素的数加上,因为子元素现在已知了
      console.log(arr);
     if (isArray(arr)) {
         for (i in arr) {
             (function(j) {
             setTimeout(function() {
                 foo(arr[j], cb);
             }, 0);
             })(i);
         }
     }
     if ((--cbCounter === 0) && (typeof cb === ‘function‘)) cb(); // 前面的--就是把自己刨出去
 }
 foo([[1, 2], [3, 4]], function() {
      console.log(‘I am a callback!‘);
 });
 

/*
 输出:
 [[1,2],[3,4]]
 [1,2]
 [3,4]
 1
 2
 3
 4
 I am a callback!
 */

时间: 2024-10-14 06:21:27

js setTimeout深度递归后完成回调的相关文章

JS 动态加载脚本 执行回调[transfer]

JS 动态加载脚本 执行回调 关于在javascript里面加载其它的js文件的问题可能很多人都遇到过,但很多朋友可能并不知道怎么判断我们要加载的js文件是否加载完成,如果没有加载完成我们就调用文件里面的函数是不会成功的.本文讲解怎么在js中加载其它js文件并在加载完成后执行回调函数. 我们可以动态的创建 <script> 元素,然后通过更改它的 src 属性来加载脚本,但是怎么知道这个脚本文件加载完成了呢,因为我们有些函数需要在脚本加载完成生效后才能开始执行. 经过对网络上资源的搜索,我发现

js setTimeout()的使用

一.语法 setTimeout(code,millisec) code:是含有 JavaScript 语句的字符串.这个语句可能诸如 "alert('5 seconds!')",或者对函数的调用,诸如 alertMsg(). millisec:指示从当前起多少毫秒后执行第一个参数. 二.setTimeout(code,millisec)中code包含形参的用法 例如 var msg='dfdsf'; setTimeout(alert(msg),1000); //alert(msg)会被

JS 动态加载脚本 执行回调

JS 动态加载脚本  执行回调 关于在javascript里面加载其它的js文件的问题可能很多人都遇到过,但很多朋友可能并不知道怎么判断我们要加载的js文件是否加载完成,如果没有加载完成我们就调用文件里面的函数是不会成功的.本文讲解怎么在js中加载其它js文件并在加载完成后执行回调函数. 我们可以动态的创建 <script> 元素,然后通过更改它的 src 属性来加载脚本,但是怎么知道这个脚本文件加载完成了呢,因为我们有些函数需要在脚本加载完成生效后才能开始执行. 经过对网络上资源的搜索,我发

UIWebView与JS的深度交互

事情的起因还是因为项目需求驱动.折腾了两天,由于之前没有UIWebView与JS交互的经历,并且觉得这次在功能上有一定的创造性,特此留下一点文字,方便日后回顾. 我要实现这样一个需求:按照本地的CSS文件展示一串网络获取的带HTML格式的只有body部分的文本,需要自己拼写完整的HTML.除此之外,还需要禁用获取的HTML文本中自带的 < img > 标签自动加载,并把下载图片的操作放在native端来处理,并通过JS将图片在Cache中的地址返回给UIWebview. 之所以要把图片操作放在

UIWebView与JS的深度探究

事情的起因还是因为项目需求驱动.折腾了两天,由于之前没有UIWebView与JS交互的经历,并且觉得这次在功能上有一定的创造性,特此留下一点文字,方便日后回顾. 我要实现这样一个需求:按照本地的CSS文件展示一串网络获取的带HTML格式的只有body部分的文本,需要自己拼写完整的HTML.除此之外,还需要禁用获取的HTML文本中自带的 < img > 标签自动加载,并把下载图片的操作放在native端来处理,并通过JS将图片在Cache中的地址返回给UIWebview. 之所以要把图片操作放在

UIWebView与JS的深度交互-b

要实现这样一个需求:按照本地的CSS文件展示一串网络获取的带HTML格式的只有body部分的文本,需要自己拼写完整的 HTML.除此之外,还需要禁用获取的HTML文本中自带的 < img >  标签自动加载,并把下载图片的操作放在native端来处理,并通过JS将图片在Cache中的地址返回给UIWebview.之所以要把图片操作放在native端做的好处在于:1.可以进行本地缓存,下次进入这篇文章可以直接从缓存读取,提高响应速度并且节省用户流量.2.可以实现点击图片放大.保存图片到相册等操作

JS做深度学习1——偶然发现与入门

JS做深度学习1--偶然发现与入门 不久前,我初次涉猎了Node.js,并且使用它开发了毕业设计的WEB模块,然后通过在Node中调用系统命令执行Python文件方式实现了深度学习功能模块的对接,Python代码的介入,让JS代码显得很累赘,我说过我很爱ES6以后的JS并且很讨厌Python的代码风格,无奈,我在写毕设那会Google还没有正式发布基于JS的深度学习框架,好吧,其实我对这事已经抱怨了很久,但是我的"呼声"仿佛很快就被Google"认同了"(滑稽),就

js jquery插入元素后事件会被注销

  js jquery插入元素后事件会被注销 document.body.innerHTML += <div id="dd">test</div>  //这个会注销事件 $(document.body).append(str);//使用这个 也可以绑定事件. 例子: //快捷键双击 $(".app_shortcut_item").dblclick(function () { var id = $(this).attr("id&quo

js实现域名判断后跳转到指定网址

js实现域名判断后跳转到指定网址,也适用于同一虚拟空间放多个网站: <script>       try           {               if(self.location == "http://apple.ya37.com/")               {                   top.location.href = "http://ya37.com/apple/";               }