在我的Grails 3.3 Web应用程序中,我需要将对不同群集/位置的多个REST调用的响应合并到一个变量中。
作为快速原型,我使用了线程。
注意:在下面的所有示例中,我都从每个集群中收集ID列表,为简单起见,我使用的是单个集群(属于Cluster
域类)。
List<Cluster> clusters = Cluster.findAllByIdInList(['london'])
CopyOnWriteArrayList ids = []
// ↓ to refactor
List<Thread> threads = []
clusters.each { Cluster cluster ->
Thread t = new Thread() {
public void run() {
ClusterDownloader.ListResponse res = ClusterDownloader.getIds(cluster)
println "Thread $cluster.id - $res"
def clusterIds = (List) res.id ?: []
ids.addAll(clusterIds)
}
}
threads.add(t)
t.start()
}
for(Thread t: threads)
t.join()
println "++ $ids"
// ↑
在这种情况下,标准输出如预期的那样显示:
Thread london - [[id:01641c64b178c0a8520e17bc75d5728541b3,time:1529484934104]]
++ [01641c64b178c0a8520e17bc75d5728541b3]
我对Grails Async框架有所了解,并尝试将上述代码重构为:
// ↓ refactored
PromiseList promises = []
clusters.each { Cluster cluster ->
Promise p = Promises.task {
ClusterDownloader.getIds(cluster)
}
p.onComplete { ClusterDownloader.ListResponse res ->
println "onComplete START $cluster.id - $res"
def clusterIds = (List) res.id ?: []
ids.addAll(clusterIds)
println "onComplete END $cluster.slug - $ids"
}
promises.add(p)
}
println "++ 1 ++ $ids"
Promises.waitAll(promises)
println "++ 2 ++ $ids"
// ↑
但在这种情况下,输出为:
++ 1 ++ []
++ 2 ++ []
onComplete START london - [[id:01641c64b178c0a8520e17bc75d5728541b3,time:1529484934104]]
onComplete END london - [01641c64b178c0a8520e17bc75d5728541b3]
好像.waitAll
方法在返回london
集群的响应后,但在执行onComplete
之前释放。
这实际上不是我所期望的,所以我尝试将onComplete
方法链接到task
定义:
Promise p = Promises.task { ... }
.onComplete { ... }
但是后来,我得到了甚至更奇怪的结果,似乎是println
的半随机组合:
1.a。 onComplete
的两次执行,id翻倍
++ 1 ++ []
onComplete START london - [[id:01641c64b178c0a8520e17bc75d5728541b3,time:1529484934104]]
onComplete START london - [[id:01641c64b178c0a8520e17bc75d5728541b3,time:1529484934104]]
onComplete END london - [01641c64b178c0a8520e17bc75d5728541b3, 01641c64b178c0a8520e17bc75d5728541b3]
onComplete END london - [01641c64b178c0a8520e17bc75d5728541b3, 01641c64b178c0a8520e17bc75d5728541b3]
++ 2 ++ [01641c64b178c0a8520e17bc75d5728541b3, 01641c64b178c0a8520e17bc75d5728541b3]
1.b。上面的变种
++ 1 ++ []
onComplete START london - [[id:01641c64b178c0a8520e17bc75d5728541b3,time:1529484934104]]
onComplete START london - [[id:01641c64b178c0a8520e17bc75d5728541b3,time:1529484934104]]
onComplete END london - [01641c64b178c0a8520e17bc75d5728541b3, 01641c64b178c0a8520e17bc75d5728541b3]
++ 2 ++ [01641c64b178c0a8520e17bc75d5728541b3, 01641c64b178c0a8520e17bc75d5728541b3]
onComplete END london - [01641c64b178c0a8520e17bc75d5728541b3, 01641c64b178c0a8520e17bc75d5728541b3]
2-两次执行,第二次不参与结果
++ 1 ++ []
onComplete START london - [[id:01641c64b178c0a8520e17bc75d5728541b3,time:1529484934104]]
onComplete END london - [01641c64b178c0a8520e17bc75d5728541b3]
++ 2 ++ [01641c64b178c0a8520e17bc75d5728541b3]
onComplete START london - [[id:01641c64b178c0a8520e17bc75d5728541b3,time:1529484934104]]
onComplete END london - [01641c64b178c0a8520e17bc75d5728541b3, 01641c64b178c0a8520e17bc75d5728541b3]
我想我真的在这里缺少什么,真的很欢迎任何帮助。预先感谢!