V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐关注
Meteor
JSLint - a JavaScript code quality tool
jsFiddle
D3.js
WebStorm
推荐书目
JavaScript 权威指南第 5 版
Closure: The Definitive Guide
waiaan
V2EX  ›  JavaScript

问一个递归执行顺序的问题

  •  
  •   waiaan · 2017-10-18 09:12:15 +08:00 · 3629 次点击
    这是一个创建于 2600 天前的主题,其中的信息可能已经有所发展或是发生改变。
    function fn1(){
    fn1(); //(1)
    fn2(); //(2)
    }
    大致这么一个顺序,请问是必须等(1)的递归执行完之后才会执行(2)吗?
    谢谢。
    28 条回复    2017-10-19 14:12:10 +08:00
    123s
        1
    123s  
       2017-10-18 09:15:10 +08:00
    fn2 不会执行吧
    brickyang
        2
    brickyang  
       2017-10-18 09:18:14 +08:00 via iPhone
    你这个递归没有退出条件,会无限死循环
    waiaan
        3
    waiaan  
    OP
       2017-10-18 09:18:39 +08:00
    @brickyang
    @123s
    只是举个例子
    BBCCBB
        4
    BBCCBB  
       2017-10-18 09:18:56 +08:00
    是的,
    但是你这个代码写的有问题, 没有出口, 导致了死循环.
    yulitian888
        5
    yulitian888  
       2017-10-18 09:20:30 +08:00
    @123s 只要不是死循环,fn2 应该被执行。
    但是楼主问的“执行完之后”的“后”怎么算呢,每一个循环体里都要被执行一次 fn2,对外层的 fn1 调用可以算“后”,但是同级来开,fn2 就是 fn1 的一部分
    waiaan
        6
    waiaan  
    OP
       2017-10-18 09:20:30 +08:00
    @BBCCBB
    我知道,只是举个例子说明一下我的问题。
    关注点在执行顺序上。
    Damon4V
        7
    Damon4V  
       2017-10-18 09:25:56 +08:00
    顺序 fn1.....fn1 -> fn2....fn2
    polun
        8
    polun  
       2017-10-18 09:28:08 +08:00   ❤️ 1
    不知道楼主是不是这个意思:

    var times = 1;

    function fun1() {
    console.log(times + ' fun1...');
    if (times++ < 9) {
    fun1();
    }

    fun2();
    console.log('--- 我是分割线 ---');
    }

    function fun2() {
    console.log(times + ' fun2...');
    }

    fun1();

    自己可以试试
    secondwtq
        9
    secondwtq  
       2017-10-18 09:29:52 +08:00 via iPhone
    可以去看看二叉树的遍历
    zheng5200
        10
    zheng5200  
       2017-10-18 09:31:48 +08:00 via iPhone
    是的,前一个执行完了,才会执行下一个
    waiaan
        11
    waiaan  
    OP
       2017-10-18 09:41:49 +08:00
    @secondwtq
    就是从这来的,这一段没看懂。
    waiaan
        12
    waiaan  
    OP
       2017-10-18 09:47:03 +08:00
    @polun 多谢。
    zhaoweichen
        13
    zhaoweichen  
       2017-10-18 09:48:28 +08:00   ❤️ 1
    假设 fn1 有正常的判断条件
    fn1_level0 => fn1_level1 => ... => fn1_leveln => fn2_leveln => fn2_leveln-1 => ... fn2_level0

    lz 需要补一补函数调用和 stack 的维护
    waiaan
        14
    waiaan  
    OP
       2017-10-18 11:47:04 +08:00
    @zhaoweichen 谢谢
    JKeita
        15
    JKeita  
       2017-10-18 15:10:54 +08:00
    每个递归层次,fn2 都会在 fn1 执行完后执行
    waiaan
        16
    waiaan  
    OP
       2017-10-18 17:42:37 +08:00
    @JKeita 然而并不是
    JKeita
        17
    JKeita  
       2017-10-19 09:03:59 +08:00
    你自己写个函数试下就清楚了,同级下 fn2 绝对是在 fn1 执行完后执行。
    JKeita
        18
    JKeita  
       2017-10-19 09:12:24 +08:00
    @waiaan
    function fn1($i)
    {
    if($i == 0){
    return;
    }
    fn1(--$i);
    echo "fn1:$i done. \n";
    fn2();
    }

    function fn2()
    {
    echo "exec fn2 \n";
    }

    fn1(3);

    输出结果:
    fn1:0 done.
    exec fn2
    fn1:1 done.
    exec fn2
    fn1:2 done.
    exec fn2
    waiaan
        19
    waiaan  
    OP
       2017-10-19 09:47:18 +08:00
    @JKeita 谢谢,请教一下为什么和 8 楼的执行顺序不一样?
    JKeita
        20
    JKeita  
       2017-10-19 09:48:38 +08:00
    @waiaan 8 楼那个写的就是错的,他用循环调用 fn1,而且输出也是在递归之前就执行了
    JKeita
        21
    JKeita  
       2017-10-19 09:51:07 +08:00
    @waiaan 看出他不是循环调用,他是在递归调用 fn1 之前就执行 console.log 进行输出,所以不一样
    waiaan
        22
    waiaan  
    OP
       2017-10-19 10:56:26 +08:00
    @JKeita


    var inOrderTraverseNode = function (node, callback) {
    if (node !== null) {
    inOrderTraverseNode(node.left, callback); //( 1 )
    callback(node.key);
    inOrderTraverseNode(node.right, callback);
    }
    };

    那这一段二叉树遍历的代码能否解释一下?为什么会等( 1 )递归结束了才开始执行后面的语句?实在没看懂,谢谢。
    JKeita
        23
    JKeita  
       2017-10-19 11:11:10 +08:00
    @waiaan 这里需要画二叉树会看得比较清楚,每次进入父节点函数时先递归左分支,左分子递归结束返回后紧接着执行父节点的 callback 回调方法,最后递归右分支。你这个是二叉树的中序遍历,具体你网上查查图片会看得比较清楚
    JKeita
        24
    JKeita  
       2017-10-19 11:17:16 +08:00
    @waiaan 为什么会等( 1 )递归结束了才开始执行后面的语句? 这里也是指 同级下执行顺序为 左,父,右
    waiaan
        25
    waiaan  
    OP
       2017-10-19 12:01:53 +08:00
    @JKeita
    18 楼和 22 楼的代码差别在哪?一个每次进入 fn1 都会执行后面的“ echo "fn1:$i done. \n";”,一个要等到 inOrderTraverseNode 递归结束才会执行后面的“ callback(node.key);”
    多谢。
    vankid
        26
    vankid  
       2017-10-19 13:16:24 +08:00
    单线的,f1 退出后开始一个个反向执行 f2
    JKeita
        27
    JKeita  
       2017-10-19 14:02:30 +08:00
    @waiaan 你还是没理解啊,并没有差别,同级下左分支 inOrderTraverseNode 执行完后必定会 callback(node.key);,你要把递归是从最深层次开始每层执行完后再返回上层继续执行,同一层次 必定 会 先后 执行 inOrderTraverseNode(left);callback;inOrderTraverseNode(right);
    JKeita
        28
    JKeita  
       2017-10-19 14:12:10 +08:00
    @waiaan
    https://gss0.bdstatic.com/94o3dSag_xI4khGkpoWK1HF6hhy/baike/c0%3Dbaike92%2C5%2C5%2C92%2C30/sign=cda010f5f9deb48fef64a98c9176514c/79f0f736afc379313a0f0cbde1c4b74543a9113a.jpg
    如图,为二叉树中序遍历,callback 函数即为输出节点名称,输出为:D J G B H E A F I C.
    每个节点即为递归层次,输出顺序为:当前节点的左节点名称,当前节点名称,当前节点的右节点名称。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2488 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 38ms · UTC 01:21 · PVG 09:21 · LAX 17:21 · JFK 20:21
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.