我有一个Play 2.4(基于Java)的应用程序,其中一些后台Akka任务实现为返回Promise的函数。
在Task1完成其工作之前,Task2无法运行。 Task3无法在Task2之前运行。我试图通过这样的Promise.map()
序列运行它们:
protected F.Promise run() throws WebServiceException {
return bankAPI.downloadBankStatements().map(
result -> bankProc.processBankStatements().map(
_result -> accounting.checkCustomersBalance()));
}
我的印象是,第一张地图将等到Task1完成,然后它将调用Task2,依此类推。当我查看应用程序(任务正在将一些调试信息写入日志)时,我可以看到,这些任务是并行运行的。
我还试图使用Promise.flatMap()
和Promise.sequence()
但没有运气。任务总是并行运行。
我知道Play本质上是非阻塞应用程序,但在这种情况下我真的需要按正确顺序执行操作。
是否有关于如何以选定的顺序运行多个Promise的一般做法?
答案 0 :(得分:0)
您已将第二个电话嵌套到map
,这意味着此处发生的是
相反,你需要链接它们:
protected F.Promise run() throws WebServiceException {
return bankAPI.downloadBankStatements()
.map(statements -> bankProc.processBankStatements())
.map(processedStatements -> accounting.checkCustomersBalance());
}
我注意到你没有使用result
或_result
(为了清楚起见我已重命名) - 这是故意的吗?
答案 1 :(得分:0)
好吧,我找到了解决方案。正确答案是:
如果你按照我的方式链接多个Promise。这意味着,作为map()
函数的回报,您期望另一个Promise.map()
函数等等,您应该遵循以下规则:
map()
flatMap()
我的案例的正确代码段是:
return bankAPI.downloadBankStatements().flatMap(result -> {
return bankProc.processBankStatements().flatMap(_result -> {
return accounting.checkCustomersBalance().map(__result -> {
return null;
});
});
});
这个解决方案很久以前就被提出来了,但最初并没有起作用。问题是,我有一个隐藏的Promise.map()
内部函数downloadBankStatements()
所以在这种情况下flatMaps链被破坏了。