两个 Promise 同时

Posted

技术标签:

【中文标题】两个 Promise 同时【英文标题】:Two Promises simultaneously 【发布时间】:2016-04-07 12:32:53 【问题描述】:

我正在开发一个 Play 应用程序,该应用程序与其他 3rd 方服务进行大量通信(检索数据)。我想做的是“组合”每个请求的结果。

更准确地说。我有三个外部 WSRequest,每个都封装在一个类中,该类具有一个方法,该方法将执行请求、检索 JSON 字符串并返回一个对象列表,这些对象基本上是 JSON 的反序列化版本。极其简化,可以简化成这样。

Class A 
    function F.Promise<List<ObjA>> call();

Class B 
    function F.Promise<List<ObjB>> call(Integer id);

Class C 
    function F.Promise<List<ObjC>> call();

从我的控制器中,我调用 A、B 和 C 的对象,进行一些处理并返回一个结果,该结果是另一个对象的 JSON 字符串(我们称之为 ObjD)。

在我的控制器中,我有这样的东西:

public F.Promise<Result> compute() 
   A a = new A();
   B b = new B();
   C c = new C();

  List<ObjA> objAList = a.call().get(TIMEOUT);
  List<ObjB> objBList = b.call(objAList.get(0).getId()).get(TIMEOUT);
  List<ObjC> objCList = c.call().get(TIMEOUT);

  // compute something using the three lists. This will create an object objD

  return F.Promise.promise(() -> ok(Json.toJson(objD)));

List 的结果取决于 A 的结果(因此不能同时调用它们)。显然,我可以简单地这样:

public F.Promise<Result> compute() 
    A a = new A();
    B b = new B();
    C c = new C();

    List<ObjC> objCList = c.call(0.get(TIMEOUT);
    return a.call().map(objAList -> 
       List<ObjB> objBList = b.call(objAList.get(0).getId()).get(TIMEOUT);
       // compute and make objD
       return Json.toJson(objD);
    );

但是我不知道是否(以及如何)同时执行对 A 和 C 的调用,并在收到两者后开始其余的处理。因此,我不想调用 C,而是等待结果,然后才调用 A,我希望能够同时触发 A 和 C 调用,并且一旦收到两者的结果,就可以对结果进行所需的计算.

谢谢

【问题讨论】:

【参考方案1】:

默认情况下,Play 中的 WS 请求是异步执行的。

这里的第一个问题是您强制 Play 等待/同步。使用F.Promise#get() 不是一个好主意。相反,您应该使用 map/flatMap 来操作响应 - 您部分是通过调用服务 A 来完成的。

如果您进一步查看 F.Promise API - 有一个名为 sequence 的方法 - 您可以使用该方法 - 只需将您的所有承诺收集在一个列表中并调用 F.Promise.sequence(myPromises) - 您将获得一个针对结果列表 - 然后您可以使用它来生成对象 D。

【讨论】:

使用序列将不起作用,因为它期望两个 Promise 具有相同的类型。但是,一个是 Promise>,另一个是 Promise>。另外,我试图不再使用 .get(),但是我需要的计算依赖于来自所有三个请求的数据。

以上是关于两个 Promise 同时的主要内容,如果未能解决你的问题,请参考以下文章

async-await 同时触发(等待)多个异步操作

如何使用pg-promise同时从多个查询中获得结果?

promise 对象之 deferred 对象 portal 实例环境搭建

promise知识

Promise.all 同时或并行运行 [重复]

Promise如何使用?全方位解析,5分钟搞懂异步#yyds干货盘点#