- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有一个树结构,我想使用 Promises 遍历它,但我还没有找到适合它的代码模式。
假设我们得到了节点名称,并且将节点名称转换为节点的行为是一个异步过程(例如涉及网络访问)。还假设每个节点包含一个(可能为空)子名称列表:
function getNodeAsync(node_name) {
// returns a Promise that produces a node
}
function childrenNamesOf(node) {
// returns a list of child node names
}
我希望以具有此签名的方法结束:
function walkTree(root_name, visit_fn) {
// call visit_fn(root_node), then call walkTree() on each of the
// childrenNamesOf(root_node), returning a Promise that is fulfilled
// after the root_node and all of its children have been visited.
}
它返回一个在根节点及其所有子节点都被访问后完成的 Promise,因此它可能被调用如下:
walkTree("grandpa", function(node) { console.log("visiting " + node.name); })
.then(function(nodes) { console.log("found " + nodes.length + " nodes.")});
I've create a gist that shows my first attempt .我对 walkTree() 的(有点错误的)实现是:
function walkTree(node_name, visit_fn) {
return getNodeAsync(node_name)
.then(function(node) {
visit_fn(node);
var child_names = childrenNamesOf(node);
var promises = child_names.map(function(child_name) {
walkTree(child_name, visit_fn);
});
return Promise.all(promises);
});
};
这会以正确的顺序访问节点,但最外层的 Promise 在访问所有子节点之前就解析了。 See the gist for full details .
正如@MinusFour 指出的那样,使用这种技术来展平节点列表是毫无意义的。事实上,我真的只想在所有节点都被访问后触发最终的 promise ,所以一个更现实的用例是:
walkTree("grandpa", function(node) { console.log("visiting " + node.name); })
.then(function() { console.log("finished walking the tree")});
最佳答案
好吧,处理每个节点的函数调用不是什么大问题,但收集节点值有点问题。走那棵树有点难,最好的办法是将它映射到一棵没有最终值的树。你可以使用类似的东西:
function buildTree(root_name) {
var prom = getNodeAsync(root_name);
return Promise.all([prom, prom.then(function(n){
return Promise.all(childrenNamesOf(n).map(child => buildTree(child)))
})]);
}
从那里你可以:
var flatTree = buildTree(root_name).then(flatArray);
flatTree.then(nodes => nodes.forEach(visit_fn));
flatTree.then(nodes => whateverYouWantToDoWithNodes);
要展平数组,您可以使用:
function flatArray(nodes){
if(Array.isArray(nodes) && nodes.length){
return nodes.reduce(function(n, a){
return flatArray(n).concat(flatArray(a));
});
} else {
return Array.isArray(nodes) ? nodes : [nodes];
}
}
老实说,如果你想要一个节点列表,使用树遍历器是没有意义的,你最好将它展平,然后迭代元素,但如果你愿意,你可以遍历数组树。
关于javascript - 带着 promise 走一棵树,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36624131/
我想递归地遍历一个目录,但我希望 python 在遇到包含超过 100 个文件的目录时从任何单个 listdir 中断。基本上,我正在搜索 (.TXT) 文件,但我想避免使用包含大型 DPX 图像序列
我正在尝试遍历列表(例如 sql 行)并为每一行触发例程。问题是传递给函数的值不会在运行时进行评估,因此根据函数执行所需的时间,它可能会使用下一行中的任何值而不是当前行。 我知道我可以在普通函数中提取
我需要以毫秒为单位的时间来处理大量事务,因此我想要正确且快速的东西。下面的工作会做得最好吗? : iMilli := int((time.Nanoseconds() % 1e6) / 1e3
我有以下目录/文件设置(已简化): Ce +---top.txt +---X0.0 | | | +---Y0.0 | | | | |
我遇到了类似的问题: Connecting to Redis To Go with PHP 基本上,我在 redis 中有这个 uri: redis://myusername:foopassword@
我阅读了下面的主题 Go: multiple value in single-value context 但我不明白这个解释在我的案例中。可能是因为我想使用 interface 在下面的情况下,我得到
我有一个模板,我想使用 text/template 评估各个字段包裹。我很难弄清楚评估应该如何工作,因为下面的代码似乎失败了。模板包是否足够强大以处理此类评估? type something stru
我编写了简单的服务器程序来从客户端接收数据。我有点不明白有时我从函数中得到错误 read tcp4 IP:PORT i/o timeoutint, err := conn.Read([]byte) 未
我只需要解码和更新 json 对象的特定值。问题是我不知道对象的完整结构。 encoding/json 包“忽略”/截断结构中未提供的字段,因此在编码时这些字段将丢失。 我想知道是否可以只解码我知道的
我正在尝试使用带有 C++ 目标的 ANTLR4 来实现 TSql 解析器。我抓取了语法文件 here .该jar用于制作相应的源文件(因冲突将TSqlParser.cpp中的NULL全部改为null
我在 win7 中使用 python 3.3.3 - 我只想列出网络目录中的所有文件。 import os for root, dirs, files in os.walk("X:\\network\
当我运行 go 脚本 ( go run example.go ) 时出现此错误 /home/travis/.gvm/gos/go1.1.2/src/pkg/github.com/user/exampl
我正在尝试通过 gmail API 发送电子邮件使用 Go但我发现文档非常有缺陷/令人困惑。这一次我看不到收据字段和电子邮件正文。 我不需要上传任何东西,所以我找到了 Simple upload ,
本人是一名专业的windows/.Net开发者,一直在慢慢学习rails/ruby/python/etc。在我有空的时候。在过去 8 年左右的时间里,我也一直在使用各种 Linux 发行版。然而,有一
我想知道是否可以使用 std http 来响应 http 请求打包并仍然保持 go 例程事件(例如运行任务密集型任务)。用例是我需要接收一个 http 请求,然后在几分钟后回调该服务 最佳答案 只需从
我想知道关于指针的最佳实践是什么。我应该在结构上还是在其字段上定义它们。我虽然定义一个指向结构本身的指针是有意义的,但这里有一个我觉得很有趣的例子。如果所有字段都是指针,为什么我不应该使用指向整个结构
我是一名优秀的程序员,十分优秀!