【问题标题】:Can't return the last result of recursion function无法返回递归函数的最后结果
【发布时间】:2021-09-01 18:30:33
【问题描述】:
  • 我正在尝试遍历以下对象
var videoElements =  {
    name: "div",
    attr: {
        id: "video-container"
    },
    children: [
        {
            name: "div",
            attr: {
                class: "video-overlay"
            },
            children: [
                {
                    name: "div",
                    attr: {
                        class: "video-top"
                    },
                    children: [
                        {
                            name: "div",
                            attr: {
                                 class: "video-settings"
                            },
                            children: [
                                {
                                    name: "i",
                                    attr: {
                                        class: "fas fa-cog"
                                    }
                                }
                            ]
                        }
                    ]
                },
                {
                    name: "div",
                    attr: {
                        class: "video-middle"
                    },
                    children: [
                        {
                            name: "div",
                            attr: {
                                class: "video-play-btn"
                            },
                            children: [
                                {
                                    name: "i",
                                    attr: {
                                        class: "fas fa-play"
                                    }
                                }
                            ]
                        }
                    ]
                },
                {
                    name: "div",
                    attr: {
                        class: "video-bottom"
                    },
                    children: [
                        {
                            name: "div",
                            attr: {
                                class: "video-bottom-btns"
                            },
                            children: [
                                {
                                    name: "div",
                                    attr: {
                                        class: "video-screen-btn"
                                    },
                                    children: [
                                        {
                                            name: "i",
                                            attr: {
                                                class: "fas fa-expand"
                                            }
                                        }
                                    ]
                                },
                                {
                                    name: "div",
                                    attr: {
                                        class: "video-volume-btn"
                                    },
                                    children: [
                                        {
                                            name: "i",
                                            attr: {
                                                class: "fas fa-volume-up"
                                            }
                                        }
                                    ]
                                },
                                {
                                    name: "div",
                                    attr: {
                                        class: "video-download-btn"
                                    },
                                    children: [
                                        {
                                            name: "i",
                                            attr: {
                                                class: "fas fa-arrow-down"
                                            }
                                        }
                                    ]
                                }
                            ]
                        },
                        {
                            name: "div",
                            attr: {
                                class: "video-seek"
                            },
                            children: [
                                {
                                    name: "div",
                                    attr: {
                                        class: "video-buffer"
                                    },
                                    children: [
                                        {
                                            name: "div",
                                            attr: {
                                                class: "video-seekable"
                                            }
                                        }
                                    ]
                                }
                            ]
                        }
                    ]
                }
            ]
        },
        {
            name: 'div',
            attr: {
                class: 'loading-overlay'
            },
            children: [
                {
                    name: 'div',
                    attr: {
                        class: 'loader'
                    }
                }
            ]
        }
    ]
}
  • 我使用递归函数从上面的对象中获取 html 元素

这是我的功能

function recursion(obj, elem, parentElem) {
    var loopObj = new Promise((resolve, reject) => {
        setTimeout(function() {
            if (obj.constructor === Object) {
                for(i in obj) {
                    if (i === 'name') {
                        parentElem = document.createElement(obj.name)
                    }
                    if (i === 'attr') {
                        for(q in obj.attr) {
                            parentElem.setAttribute(q, obj.attr[q])
                        }
                    }
                    if (i === 'children') {
                        for(r = 0; r < obj[i].length; r++) {
                            if (obj[i][r].name) {
                                var child =document.createElement(obj[i][r].name)
                            }
                            if (obj[i][r].attr) {
                                for(w in obj[i][r].attr) {
                                    child.setAttribute(w, obj[i][r].attr[w])
                                }
                                parentElem.append(child)
                            }
                            if (obj[i][r].children) {
                                recursion(obj[i][r].children, child, parentElem)
                            }
                        }
                    }
                }
            } else if (obj.constructor === Array) {
                for(i = 0; i < obj.length; i++) {
                    if (obj[i].name) {
                        var child = document.createElement(obj[i].name)
                    }
                    if (obj[i].attr) {
                        for(w in obj[i].attr) {
                            child.setAttribute(w, obj[i].attr[w])
                        }
                    }
                    elem.append(child);
                    if (obj[i].children) {
                        recursion(obj[i].children, child, parentElem)
                    }
                }
                //stop the function here
                return
            }
            if(parentElem) resolve(parentElem)
        })
    })
    loopObj.then(function(htmElem) {
        console.log(htmElem);
        return htmElem;
    })
}
var elements = recursion(videoElements);
console.log(elements);
  • 问题是当我在控制台中查找结果时,我正常找到了该元素,但我无法返回它,因为我已经多次调用该函数,所以当我尝试编写 console.log(elements) 时,它给出了我未定义我正在考虑使用Promise.all,但我不知道如何获取此函数的数组,所以我需要有人帮助我在调用函数时正常获得最后一个结果

已编辑

预期结果

<div id="video-container">
  <div class="video-overlay">
    <div class="video-top">
      <div class="video-settings">
        <i class="fas fa-cog"></i>
      </div>
    </div>
    <div class="video-middle">
      <div class="video-play-btn">
        <i class="fas fa-play"></i>
      </div>
    </div>
    <div class="video-bottom">
      <div class="video-bottom-btns">
        <div class="video-screen-btn">
            <i class="fas fa-expand"></i>
        </div>
        <div class="video-volume-btn">
            <i class="fas fa-volume-up"></i>
        </div>
        <div class="video-download-btn">
            <i class="fas fa-arrow-down"></i>
        </div>
      </div>
      <div class="video-seek">
        <div class="video-buffer">
          <div class="video-seekable"></div>
        </div>
      </div>
    </div>
  </div>
  <div class="loading-overlay">
    <div class="loader"></div>
  </div>
</div>

【问题讨论】:

  • 如何首先构建一个以“更简单”的方式保存数据的数据结构,然后编写一个算法来操作该数据结构?
  • 什么意思
  • 什么是recuration?你几乎从不resolve 任何东西。
  • 对不起,我在发布问题时更改了函数名称 - 我忘记正确编辑名称 - 无论如何我编辑了它,你现在可以尝试
  • 你的“recusrsion”函数绝对不会返回任何东西——而且,每次你调用recursion它都会创建一个Promise,它只解决了一半的时间——你最终会得到大量未解决的承诺。您最初也只使用一个参数调用递归,并且在您的代码中没有任何地方可以看到测试是否给出了其他参数,因此elem.append 将失败,并且parentElem 可能在您parentElem.setAttribute 时未定义。 . 最后,为什么你的代码使用 Promises 和 setTimeout?

标签: javascript arrays loops object recursion


【解决方案1】:

我希望下面的代码能如你所愿。

    name: "div",
    attr: {
        id: "video-container"
    },
    children: [
        {
            name: "div",
            attr: {
                class: "video-overlay"
            },
            children: [
                {
                    name: "div",
                    attr: {
                        class: "video-top"
                    },
                    children: [
                        {
                            name: "div",
                            attr: {
                                class: "video-settings"
                            },
                            children: [
                                {
                                    name: "i",
                                    attr: {
                                        class: "fas fa-cog"
                                    }
                                }
                            ]
                        }
                    ]
                },
                {
                    name: "div",
                    attr: {
                        class: "video-middle"
                    },
                    children: [
                        {
                            name: "div",
                            attr: {
                                class: "video-play-btn"
                            },
                            children: [
                                {
                                    name: "i",
                                    attr: {
                                        class: "fas fa-play"
                                    }
                                }
                            ]
                        }
                    ]
                },
                {
                    name: "div",
                    attr: {
                        class: "video-bottom"
                    },
                    children: [
                        {
                            name: "div",
                            attr: {
                                class: "video-bottom-btns"
                            },
                            children: [
                                {
                                    name: "div",
                                    attr: {
                                        class: "video-screen-btn"
                                    },
                                    children: [
                                        {
                                            name: "i",
                                            attr: {
                                                class: "fas fa-expand"
                                            }
                                        }
                                    ]
                                },
                                {
                                    name: "div",
                                    attr: {
                                        class: "video-volume-btn"
                                    },
                                    children: [
                                        {
                                            name: "i",
                                            attr: {
                                                class: "fas fa-volume-up"
                                            }
                                        }
                                    ]
                                },
                                {
                                    name: "div",
                                    attr: {
                                        class: "video-download-btn"
                                    },
                                    children: [
                                        {
                                            name: "i",
                                            attr: {
                                                class: "fas fa-arrow-down"
                                            }
                                        }
                                    ]
                                }
                            ]
                        },
                        {
                            name: "div",
                            attr: {
                                class: "video-seek"
                            },
                            children: [
                                {
                                    name: "div",
                                    attr: {
                                        class: "video-buffer"
                                    },
                                    children: [
                                        {
                                            name: "div",
                                            attr: {
                                                class: "video-seekable"
                                            }
                                        }
                                    ]
                                }
                            ]
                        }
                    ]
                }
            ]
        },
        {
            name: 'div',
            attr: {
                class: 'loading-overlay'
            },
            children: [
                {
                    name: 'div',
                    attr: {
                        class: 'loader'
                    }
                }
            ]
        }
    ]
}


function recursion(obj, elem, parentElem) {
    if (obj.constructor === Object) {
        for (i in obj) {
            if (i === 'name') {
                parentElem = document.createElement(obj.name)
            }
            if (i === 'attr') {
                for (q in obj.attr) {
                    parentElem.setAttribute(q, obj.attr[q])
                }
            }
            if (i === 'children') {
                var i = 'children'
                for (r = 0; r < obj[i].length; r++) {
                    if (obj[i][r].name) {
                        var child = document.createElement(obj[i][r].name)
                    }
                    if (obj[i][r].attr) {
                        for (w in obj[i][r].attr) {
                            child.setAttribute(w, obj[i][r].attr[w])
                        }
                        parentElem.append(child)
                    }
                    if (obj[i][r].children) {
                        recursion(obj[i][r].children, child, parentElem)
                    }
                }
            }
        }
    } else if (obj.constructor === Array) {
        for (i = 0; i < obj.length; i++) {
            if (obj[i].name) {
                var child = document.createElement(obj[i].name)
            }
            if (obj[i].attr) {
                for (w in obj[i].attr) {
                    child.setAttribute(w, obj[i].attr[w])
                }
            }
            elem.append(child);
            if (obj[i].children) {
                recursion(obj[i].children, child, parentElem)
            }
        }
        //stop the function here
        return
    }
    if (parentElem) return (parentElem)
}
var elements = recursion(videoElements);
console.log(elements);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-04
    • 2014-12-06
    • 2016-05-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多