在测序期货上输掉类型

时间:2016-02-11 11:52:00

标签: scala akka

我正在尝试这样做:

  case class ConversationData(members: Seq[ConversationMemberModel], messages: Seq[MessageModel])

  val membersFuture: Future[Seq[ConversationMemberModel]] = ConversationMemberPersistence.searchByConversationId(conversationId)

  val messagesFuture: Future[Seq[MessageModel]] = MessagePersistence.searchByConversationId(conversationId)

  Future.sequence(List(membersFuture, messagesFuture)).map{ result =>
    // some magic here

    self ! ConversationData(members, messages)
  }

但是,当我对两个期货编码器进行排序时,编译器正在丢失类型。编译器说结果类型是List [Seq [Product with Serializable]]一开始我希望做类似的事情

Future.sequence(List(membersFuture, messagesFuture)).map{ members, messages => ...

但是看起来测序期货不能像这样工作......我也尝试在地图中使用收集,但我也遇到了类似的错误。

感谢您的帮助

2 个答案:

答案 0 :(得分:2)

使用Future.sequence时,假设多个Future生成的基础类型相同(或从同一父类型扩展)。使用sequence,您基本上会将特定类型的SeqFuture转换为该特定类型的Future的{​​{1}}个Seq。一个具体的例子可能更能说明这一点:

val f1:Future[Foo] = ...
val f2:Future[Foo] = ...
val f3:Future[Foo] = ...
val futures:List[Future[Foo]] = List(f1, f2, f3)
val aggregateFuture:Future[List[Foo]] = Future.sequence(futures)

因此,您可以看到我从List Future[Foo]转到包含Future的{​​{1}}个List[Foo]。如果已经有一堆Future s用于相同类型(或基本类型)的结果,并且您希望聚合下一个处理步骤的所有结果,则可以使用此选项。 sequence方法产品是一个新的Future,在完成所有汇总的Future之前不会完成,然后它将包含所有这些Future的汇总结果Future 1}}秒。当你有一个不确定或可变数量的Future来处理时,这种方法尤其有用。

对于您的情况,似乎您有一定数量的Future来处理。正如@Zoltan所建议的那样,简单的理解可能更适合这里,因为已知for{ members <- membersFuture messages <- messagesFuture } { self ! ConversationData(members, messages) } 的数量。所以解决你的问题是这样的:

function addListItems(listTitle, propertiesToAdd) {
var ctx = SP.ClientContext.get_current();
var web = ctx.get_web();
var list = web.get_lists().getByTitle(listTitle);
var listItemCreationInfo = new SP.ListItemCreationInformation();
var newItem = list.addItem(listItemCreationInfo);
propertiesToAdd.forEach(function (entry) {
    newItem.set_item(entry.ID, entry.newval);
});
    newItem.update();
var d = $.Deferred();
ctx.executeQueryAsync(function () {
    d.resolve(true);
},
function (sender, args) {
    d.reject(args);
});
return d.promise();

可能是这个具体例子的最佳方式。

答案 1 :(得分:1)

你想通过sequence电话试图取得什么成果?我只是使用for-comprehension:

val membersFuture: Future[Seq[ConversationMemberModel]] = ConversationMemberPersistence.searchByConversationId(conversationId)
val messagesFuture: Future[Seq[MessageModel]] = MessagePersistence.searchByConversationId(conversationId)

for {
  members <- membersFuture
  messages <- messagesFuture
} yield (self ! ConversationData(members, messages))

请注意,您必须在for-comprehension之外声明两个期货,否则在messagesFuture完成之前不会提交membersFuture

您也可以使用zip

membersFuture.zip(messagesFuture).map {
  case (members, messages) => self ! ConversationData(members, messages)
}

但我更喜欢理解。

相关问题