如何使这个同步递归函数异步 [英] how to make this synchronous recursive function asynchronous

查看:131
本文介绍了如何使这个同步递归函数异步的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个递归走一棵树JavaScript函数。它具有被设置为假或上述函数本身的范围真两个旗的变量,并且因此,如果一个标志被设置为真一次而walkTree功能被递归,它会为每一个递归真。在另一方面,for循环可能存在带有返回的功能以及如果事情是。我的问题是,当有太多的递归我得到一个错误。

我想prevent通过这个递归函数异步这个问题,我已经试过把分walkTree()内的呼吁循环到setTimeout的,但我现在的问题是,休息该功能将被执行(并可能返回错误的值)的异步东西,剩下的就是之前完成。那么,如何可以让这个异步,同时还确保正确的价值将返回(而不是在递归顶级函数调用)?

正如你可以看到函数的结尾利用该FLAGB变量的所有调用共享的,所以我们需要确保所有的递归调用已完成(和返回的东西)为最上面的一个检查前,这些条件句。谢谢!

  VAR FLAGA = FALSE;
VAR FLAGB = FALSE;VAR walkTree =功能(N){
  VAR子;  对于(VAR I = 0; I< n.children.length;我++){
      分= walkTree(n.children [I]);
      如果(子==='的东西特'){
        返回子;
      }
  }  VAR测试= doSomethingWith(N);  如果(测试===东西){
    FLAGA =真;
  }  如果(测试===的东西,否则){
    FLAGB = TRUE;
  }  如果(FLAGB ===真){
    返回true;
  }
  如果(测试===事特){
    回归测试;
  }其他{
    返回false;
  }}


解决方案

亚历克斯VASI建议,你可能要考虑迭代树的遍历,而不是递归。但是,如果你的数据集是巨大的,处理数据需要花费大量的时间,你的用户界面可能会冻结。因此,你可能仍然希望异步做处理。

下面是Alex的示例进行了修改:

 函数asyncIterativeWalkTree(节点){
    VAR队列= [节点];    VAR processQueue =功能(){
        变种N = queue.shift();
        对于(VAR I = 0; I< n.children.length;我++){
            queue.push(n.children [I]);
            的setTimeout(processQueue,0);
        }
        doSomethingWith(N);
    }    processQueue();
}

上面的code片段确实迭代遍历异步,从而给一些时间给UI进行自我更新。

下面是一个的jsfiddle 在这里你可以看到同步和异步横向之间的差异。同步横移,使您的浏览器冻结的一小段时间,而异步版本给浏览器一段时间的呼吸在处理树。
(在code是有点乱,不好意思......)

编辑:更新的jsfiddle

I have a javascript function that walks a tree recursively. It has two "flag" variables that are set to false or true above the scope of the function itself, and so if a flag is set to true one time while the "walkTree" function is being recursed, it will be true for every recursion. On the other hand, the for loop might exist the function with a return as well if something is for. The problem I have is when there are too many recursions I get an error.

I'd like to prevent this problem by making this recursive function asynchronous, I've tried putting the sub walkTree() call inside the for loop into a setTimeout, but the problem I have now is that the rest of the function will be executed (and might return the wrong value) before the rest of the asynchronous stuff is done. So how can I make this asynchronous while still making sure the right value will be returned (and not the top function call in the recursion)?

As you can see the end of the function makes use of that flagB "variable" shared by all calls, and so we need to make sure all the recursive calls have been completed (and returned something) before the top one checks for these conditionals. Thanks!

var flagA = false;
var flagB = false;

var walkTree = function (n) {
  var sub;

  for (var i = 0; i < n.children.length; i++) {
      sub = walkTree(n.children[i]);
      if (sub === 'something-special') {
        return sub;
      }
  }

  var test = doSomethingWith(n);

  if (test === "something") {
    flagA = true;
  }

  if (test === "something-else") { 
    flagB = true;
  }

  if (flagB === true) {
    return true;
  }
  if (test === "something-special") {
    return test;
  } else {
    return false;
  }

}

解决方案

As alex vasi suggested, you might want to consider iterative tree traversal instead of recursive. However, if your dataset is huge and processing the data takes a lot of time, your UI may freeze. Thus, you still might want to do the processing asynchronously.

Here's a modification of alex's example:

function asyncIterativeWalkTree(node) {
    var queue = [node];

    var processQueue = function() {
        var n = queue.shift();
        for (var i = 0; i < n.children.length; i++) {
            queue.push(n.children[i]);
            setTimeout(processQueue, 0);
        }
        doSomethingWith(n);
    }

    processQueue();
}

The code snippet above does iterative traverse asynchronously, thus giving some time to the UI to update itself.

Here's a jsFiddle where you can notice the difference between synchronous and asynchronous traverse. The synchronous traverse makes your browser to freeze for a small period of time, while the asynchronous version gives browser some time to breath while processing the tree. (The code is a bit messy, sorry...)

Edit: Updated jsFiddle

这篇关于如何使这个同步递归函数异步的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆