我正在尝试使用 Promises 创建一个递归函数,但似乎不太正确。我有不使用 promises 的工作代码,但它使用了计数器和全局变量等,感觉不太正确,所以我正在尝试重写并创建一个模块以供重用。
本质上,该功能应该是从 Active Directory 中获取用户,然后递归查找任何直接下属及其直接下属等。
我玩过很多版本的函数,这是当前版本:
function loadReports(personEmail, list) {
return new Promise((resolve, reject) => {
getAccessTokenPromise()
.then(access_token => {
list.push(personEmail);
return makeRequest(personEmail, access_token);
}).then(result => {
if (result.value.length > 0) {
Promise.all(result.value.map(person => {
loadReports(person.userPrincipalName, list);
})).then(resolve());
} else {
resolve();
}
})
.catch(e => reject(e));
});
}
getAccessTokenPromise 函数执行访问 token 请求并返回一个 promise 。 makeRequest 函数再次为用户及其报告发出 https 请求,并返回一个 json 对象,并将结果作为 Promise。
任何想法都收到了。非常感谢。 D.
最佳答案
为了使递归与 promise 一起工作,您通常希望将所有递归 promise 链接到它们的调用者。为此,您必须从您的 .then() 处理程序返回任何 promise ,以便它们链接到原件。这也往往会消除你的 promise anti-pattern用一个充满问题的手动创建的 promise 来包装现有的 promise 。这是一种方法:
function loadReports(personEmail, list) {
return getAccessTokenPromise().then(access_token => {
list.push(personEmail);
return makeRequest(personEmail, access_token);
}).then(result => {
if (result.value.length > 0) {
return Promise.all(result.value.map(person => {
return loadReports(person.userPrincipalName, list);
}));
}
});
}
所做的更改:
在 getAccessTokenPromise() 之前添加 return 以便我们返回初始 promise 。这也让我们可以消除 new Promise() 以及反模式中涉及的所有手动拒绝和解决。
在递归loadReports() 之前添加return。必须这样做才能让 .map() 在将 promise 传递给 Promise.all() 之前收集该 promise 。
在 Promise.all() 之前添加 return,使其链接到原始的 promise 链。
您必须确保永远不会在数据库数据中出现任何形式的循环(数据库中的错误会创建循环报告列表)。 A 向 B 报告,B 向 C 报告,C 向 A 报告,因为如果你确实有这个,那么这段代码将永远持续下去,永远不会完成(可能最终会耗尽一些系统资源)。
如果这是我的代码,我可能会在执行过程中创建数据库中所有访问过的人的集合,并拒绝对我们之前访问过的任何人调用 loadReports()。这将使它免受循环性的影响。如果您看到这种情况,您可能还想 log(),因为它可能是数据库错误/损坏。
关于Javascript 递归 promise ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39362071/
我遇到了一个非常奇怪的问题,我很难解决。在我看来,我有一个与data-remote="true"和data-method="delete"的链接。当我单击该链接时,我可以看到对我的Rails服务器的DELETE请求。返回的JS代码会更改此链接的属性,其中包括href和data-method。再次单击此链接后,我的服务器收到了对新href的请求,但使用的是旧的data-method,即使我已将其从DELETE到POST(它仍然发送一个DELETE请求)。但是,如果我刷新页面,HTML与"new"HTML相同(随返回的JS发生变化),但它实际上发送了正确的请求类型。这就是这个问题令我困惑的
我有一个随机大小的散列,它可能有类似"100"的值,我想将其转换为整数。我知道我可以使用value.to_iifvalue.to_i.to_s==value来做到这一点,但我不确定我将如何在我的散列中递归地做到这一点,考虑到一个值可以是一个字符串,或一个数组(哈希或字符串),或另一个哈希。 最佳答案 这是一个非常简单的递归实现(尽管必须同时处理数组和散列会增加一些技巧)。deffixnumifyobjifobj.respond_to?:to_i#IfwecancastittoaFixnum,doit.obj.to_ielsifobj
我经常迷上ruby的一件事是递归模式。例如,假设我有一个数组,它可能包含无限深度的数组作为元素。所以,例如:my_array=[1,[2,3,[4,5,[6,7]]]]我想创建一个方法,可以将数组展平为[1,2,3,4,5,6,7]。我知道.flatten可以完成这项工作,但这个问题是作为我经常遇到的递归问题的一个例子-因此我试图找到一个更可重用的解决方案。简而言之-我猜这种事情有一个标准模式,但我想不出任何特别优雅的东西。任何想法表示赞赏 最佳答案 递归是一种方法,它不依赖于语言。您在编写算法时要考虑两种情况:再次调用函数的情
我有这个ruby代码:defget_sumnreturn0ifn似乎正在为999之前的值工作。当我尝试9999时,它给了我这个:stackleveltoodeep(SystemStackError)所以,我添加了这个:RubyVM::InstructionSequence.compile_option={:tailcall_optimization=>true,:trace_instruction=>false}但什么也没发生。我的ruby版本是:ruby1.9.3p392(2013-02-22revision39386)[x86_64-darwin12.2.1]我还增加了机器的堆栈大
我有这个:AccountSummary我想单击该链接,但在使用link_to时出现错误。我试过:bot.click(page.link_with(:href=>/menu_home/))bot.click(page.link_with(:class=>'top_level_active'))bot.click(page.link_with(:href=>/AccountSummary/))我得到的错误是:NoMethodError:nil:NilClass的未定义方法“[]” 最佳答案 那是一个javascript链接。Mechan
构建一个深度优先的网络蜘蛛,这意味着它将访问第一页上的所有链接,然后转到每个链接,并访问所有第二页上的链接...你应该使用递归吗?我发现这是CPU密集型的。defrecursion()linkz_on_first_page.eachdo|link|recursion(link)endendrecursion(firstpage) 最佳答案 绝对不是,由于万维网的实际性质,您很快就会遇到问题。当您访问带有主导航部分的网站时,每个页面都链接到其他页面,您就进入了一个无限循环。您可以跟踪您处理了哪些链接,但即便如此,递归循环并不真正适合万
例如,如果我有YAML文件en:questions:new:'NewQuestion'other:recent:'Recent'old:'Old'这最终会变成一个json对象,例如{'questions.new':'NewQuestion','questions.other.recent':'Recent','questions.other.old':'Old'} 最佳答案 由于问题是关于在Rails应用程序上使用YAML文件进行i18n,因此值得注意i18ngem提供了一个辅助模块I18n::Backend::Flatten完全像
我看到有关未找到文件min.map的错误消息:GETjQuery'sjquery-1.10.2.min.mapistriggeringa404(NotFound)截图这是从哪里来的? 最佳答案 如果ChromeDevTools报告.map文件的404(可能是jquery-1.10.2.min.map、jquery.min.map或jquery-2.0.3.min.map,但任何事情都可能发生)首先要知道的是,这仅在使用DevTools时才会请求。您的用户不会遇到此404。现在您可以修复此问题或禁用sourcemap功能。修复:获取文
我有一个用Rails3编写的站点。我的帖子模型有一个名为“内容”的文本列。在帖子面板中,html表单使用tinymce将“content”列设置为textarea字段。在首页,因为使用了tinymce,post.html.erb的代码需要用这样的原始方法来实现。.好的,现在如果我关闭浏览器javascript,这个文本区域可以在没有tinymce的情况下输入,也许用户会输入任何xss,比如alert('xss');.我的前台会显示那个警告框。我尝试sanitize(@post.content)在posts_controller中,但sanitize方法将相互过滤tinymce样式。例如
我有这两个gcd函数的实现:defgcd1(a,b)ifa==baelsifa>bif(a%b)==0belsegcd1(a%b,b)endelseif(b%a)==0aelsegcd1(a,b%a)endendenddefgcd2(a,b)if(a==b)returnaelsifb>amin,max=a,belsemin,max=b,aendwhile(max%min)!=0min,max=max%min,minendminend函数gcd1是尾递归的,而gcd2使用while循环。我已经验证rubinius通过对阶乘函数进行基准测试来执行TCO,只有阶乘函数基准测试显示递归版本和迭