当前位置: 首页 > 知识库问答 >
问题:

如何在Scala中违背诺言

归翔
2023-03-14

在Scala文档中,有一个例子说明了如何通过使用promise来选择更快成功的未来。

http://docs . Scala-lang . org/overviews/core/futures . html # promises

def first[T](f: Future[T], g: Future[T]): Future[T] = {
  val p = promise[T]
  f onSuccess {
    case x => p.trySuccess(x)
  }
  g onSuccess {
    case x => p.trySuccess(x)
  }
  p.future
}

这个函数返回先成功的未来,如果其中任何一个失败,它永远不会完成。

是否有可能以这样一种方式修改它,即即使其他未来失败,如果第二个成功,则返回第二个,如果两个都成功,则选择更快的一个,就像代码现在所做的那样。

共有3个答案

洪楷
2023-03-14

以下是一个基本模式,用于选择最快的未来或在它们都太慢时超时:

import scala.concurrent._
import scala.concurrent.duration._
import scala.concurrent.ExecutionContext.Implicits.global
import scala.util.{ Success, Failure }
import akka.actor._
import akka.pattern.after

object GetFastestFutureOrTimeout extends App {
  val e = new TimeoutException("TimeoutException")
  val system = ActorSystem("GetFastestFutureOrTimeout")
  val f1 = Future { Thread.sleep(200); "this is f1" }
  val f2 = Future { Thread.sleep(100); "this is f2" }
  val timeoutFuture = after(500.milliseconds, using = system.scheduler) { Future.failed(e) }
  val f = Future.firstCompletedOf(f1 :: f2 :: timeoutFuture :: Nil)

  f onComplete {
    case Success(msg) => println(msg)
    case Failure(err) => println("An error occured: " + err.getMessage)
  }
}

打印“这是f2”。如果timeoutFuture的超时时间更改为50,它将打印“发生错误:TimeoutException”。

firstCompletedOf使用一个promise来返回第一个完成的Future的值,请参见https://github . com/Scala/Scala/blob/v 2 . 11 . 6/src/library/Scala/concurrent/Future . Scala # L503。

麻书
2023-03-14

我建议您遵循阿尔文·亚历山大关于Scala未来和promise的建议

我相信这是处理期货的最佳方式

package futures

import scala.concurrent.{Future => ConcurrentTask}           // rename
import scala.concurrent.ExecutionContext.Implicits.global
import scala.util.{Failure, Success}
import Utils.sleep

object FutureAsConcurrentTask extends App {

  // run some long-running task (task has type Future[Int] in this example)
  val task = ConcurrentTask {
    Cloud.executeLongRunningTask
  }

  // whenever the task completes, execute this code
  task.onComplete {
    case Success(value) => println(s"Got the callback, value = $value")
    case Failure(e) => println(s"D'oh! The task failed: ${e.getMessage}")
  }

  // do your other work
  println("A ..."); sleep(100)
  println("B ..."); sleep(100)
  println("C ..."); sleep(100)
  println("D ..."); sleep(100)
  println("E ..."); sleep(100)
  println("F ..."); sleep(100)

}
彭弘伟
2023-03-14

您可以添加以下内容:

f onFailure {
  case e =>
    g onFailure {
      case _ =>
        p.failure(e)
    }
}

当两个期货都失败时,这将使promise失败,例外情况与< code>f相同。如果需要,您可以详细说明这一点,创建一个异常来记录来自< code>f和< code>g的两个异常

 类似资料:
  • 问题内容: 我正在尝试使用字符串方法。但是,如果我将%1,%2等放置在字符串中,则会抛出java.util.UnknownFormatConversionException,指向一个令人困惑的Java源代码片段: 从中我了解到 char是被禁止的。如果是这样,那么我应该对参数占位符使用什么? 我使用Scala 2.8。 问题答案: 尽管所有先前的回答都是正确的,但它们都是Java语言。这是一个Sc

  • 问题内容: 我怎样才能返回一个 函数 副作用的词汇封闭 1 斯卡拉? 例如,我在Go中查看此代码示例: 打印1 2 3 5 8 而且我不知道如何在Scala中编写相同的内容。 1.在Apocalisp评论后更正 问题答案: 稍短一些,您不需要退货。

  • 问题内容: 我想要的只是使用一些并发Set(看起来根本不存在)。Java用于实现该行为。我想在Scala中做类似的事情,所以我创建了Scala HashMap(或Java ConcurrentHashMap)实例,并尝试添加一些元组: 当然,由于Unit是抽象的也是最终的,因此这使编译过程崩溃了。 如何使这项工作?我应该使用/ 代替吗?我必须确保没有人插入任何值。 感谢帮助 问题答案: 您可以只使

  • 问题内容: 我有以下代码: 如您所见,期望使用lambda表达式。 现在,我正在使用Java库,但是该应用程序是用Scala编写的。如何将Scala lambda传递给Java代码? 我尝试了以下方法: 但是编译器抱怨: 问题答案: 错误消息列出了支持的参数类型。其中之一是: 从错误消息中,您可以看到您提供了以下类型: 根据Kafka 1 javadoc (在Kafka 1.1中不存在),定义为:

  • 实际上,恰恰是专有软件的理念--不允许共享或改动软件--是反社会的,也是不道德的,而且也是完全错误的。但是长期以来,软件出版商使人们相信:软件天生就该如此。这种片面的认识禁锢了人们的思维。当他们在谈论如何加强版权或打击盗版时,他们也认定这是天经地义,人们也会毫无异议地接受。 他们的第一个假设就是:软件公司对自己的软件拥有毫无疑问的天然权力,因而可以将权利施加到所有用户身上。(因为如果是天然权力,那