|
|
<div id="cnblogs_post_body">问题:
因为递归太深而使用了异步的 setTimeout 清空调用栈,整个递归变成了异步的行为,函数已经提前返回了,现在怎么设置整个递归完成后的回调?
回答:
看了问题评论才理解你的意思,我按照你的目的写了一个能调试的代码,你看看跟你问题中的代码是不是差不多:
<div class="cnblogs_code"> 1 // 无回调 2 function isArray(o) { 3 return toString.apply(o) === '[object Array]'; 4 } 5 function foo(arr) { 6 console.log(arr); 7 if (isArray(arr)) { 8 for (i in arr) { 9 (function(j) {10 setTimeout(function() {11 foo(arr[j]);12 }, 0);13 })(i);14 }15 }16 }17 foo([[1, 2], [3, 4]]);18 19 /*20 输出:21 [[1,2],[3,4]]22 [1,2]23 [3,4]24 125 226 327 428 */29 30 //有回调31 function isArray(o) {32 return toString.apply(o) === '[object Array]';33 }34 // 设置一个计数器,标识&ldquo;已知的还未被遍历的元素数量&rdquo;,起始值显然为135 var cbCounter = 1;36 function foo(arr, cb) {37 cbCounter += isArray(arr) ? arr.length : 0; // 把子元素的数加上,因为子元素现在已知了38 console.log(arr);39 if (isArray(arr)) {40 for (i in arr) {41 (function(j) {42 setTimeout(function() {43 foo(arr[j], cb);44 }, 0);45 })(i);46 }47 }48 if ((--cbCounter === 0) && (typeof cb === 'function')) cb(); // 前面的--就是把自己刨出去49 }50 foo([[1, 2], [3, 4]], function() {51 console.log('I am a callback!');52 });53 54 /*55 输出:56 [[1,2],[3,4]]57 [1,2]58 [3,4]59 160 261 362 463 I am a callback!64 */ |
|