2

我需要异步获取猫、狗和老鼠,然后进行一些后期处理。这是我正在做的事情:

Promise<List<Cat>> fetchCats  = task {}
Promise<List<Mouse>> fetchMice  = task { }
Promise<List<Dog>> fetchDogs  = task {}
List promiseList = [fetchCats, fetchMice, fetchDogs]
List results = Promises.waitAll(promiseList)

我面临的问题是,列表中的项目顺序results不固定,即在一个执行结果中可以是[cats, dogs, mice],在另一个执行中,结果可以是[dogs, mice, cats]

这意味着访问cats我需要显式检查元素的类型results,并且类似地检查dogsmice这使我的代码看起来很糟糕。

在这里浏览文档后,我发现PromiseMapAPI 可以帮助我,因为它提供了一种通过键值对访问结果的漂亮方式。这是它提供的:

import grails.async.*

def map = new PromiseMap()
map['one'] = { 2 * 2 }
map['two'] = { 4 * 4 }
map['three'] = { 8 * 8 }
map.onComplete { Map results ->
  assert [one:4,two:16,three:64] == results
} 

虽然PromiseMap有一个onComplete方法,但它不会让当前线程等待所有的承诺完成。

使用PromiseMap,我怎样才能阻塞当前线程,直到所有的承诺都完成?

4

2 回答 2

1

如果你只关心当前线程要等到 PromiseMap 完成,可以使用 Thread : join()

import grails.async.*

def map = new PromiseMap()

map['one'] = { println "task one" }
map['two'] = { println "task two" }
map['three'] = { println "task three" }

Thread t = new Thread() {
    public void run() {
        println("pausing the current thread, let promiseMap complete first")
        map.onComplete { Map results ->
            println("Promisemap processing : " + results)
        }
    }
}

t.start()
t.join()

println("\n  CurrentThread : I can won the race if you just comment t.join() line in code")
于 2017-04-27T14:12:10.000 回答
0

利用.get()

从 PromiseMap 来源:

/**
 * Synchronously return the populated map with all values obtained from promises used
 * inside the populated map
 *
 * @return A map where the values are obtained from the promises
 */
Map<K, V> get() throws Throwable {
于 2018-02-02T22:49:17.480 回答