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

promise有缺陷吗?

吴开宇
2023-03-14

像这个问题的作者一样,我试图理解Scala 2.10的期货和promise中用户可见promise的原因。

特别是,再回到SIP的例子,它是不是完全有缺陷:

import scala.concurrent.{ future, promise }
val p = promise[T]
val f = p.future
val producer = future {
  val r = produceSomething()
  p success r
  continueDoingSomethingUnrelated()
}
val consumer = future {
  startDoingSomething()
  f onSuccess {
    case r => doSomethingWithResult()
  }
}

我正在想象对produceWhat的调用会导致运行时异常的情况。因为Promise和Producer-Future是完全分离的,这意味着系统挂起,消费者永远不会成功或失败。

因此,使用promise的唯一安全方式需要类似这样的东西

val producer = future {
  try {
    val r.produceSomething()
    p success r
  } catch {
     case e: Throwable =>
       p failure e
       throw e  // ouch
  }
  continueDoingSomethingUnrelated()
}

这显然容易出错和冗长。

对于可见的 promise 类型,我能看到的唯一情况是 m. A. D. 的答案中的回调钩子之一。但是SIP的例子对我来说没有意义。

共有3个答案

昌栋
2023-03-14

Promise有一个completeWith(f:Future)方法,可以通过自动处理成功/失败场景来解决这个问题。

promise.completeWith( future {
  r.produceSomething
})
欧阳骏俊
2023-03-14

您可以使用< code>Promise来构建库中还没有的其他< code>Future组合子。

> < li>

“选择”关闭第一个未来得到满足。作为回报,剩余的期货作为一个序列:https://gist.github.com/viktorklang/4488970.

一种 after 方法,它返回在一段时间后完成的 Future,以“超时”Future:https://gist.github.com/3804710。

您需要Promises才能创建类似的其他组合器。

使用Promise使基于回调的API适应未来基于的API。例如:

def retrieveThing(key: String): Future[Thing] = {
  val p = Promise[Thing]()

  val callback = new Callback() {
    def receive(message: ThingMessage) {
      message.getPayload match {
        case t: Thing =>
          p success t        
        case err: SystemErrorPayload =>
          p failure new Exception(err.getMessage)
      }
    }
  }

  thingLoader.load(key, callback, timeout)
  p.future
}

使用Promise构建同步器。例如,为昂贵的操作返回缓存值,或计算它,但不要为同一个键计算两次:

private val cache = new ConcurrentHashMap[String, Promise[T]]

def getEntry(key: String): Future[T] = {
  val newPromise = Promise[T]()
  val foundPromise = cache putIfAbsent (key, newPromise)

  if (foundPromise == null) {
    newPromise completeWith getExpensive(key)
    newPromise.future
  } else {
    foundPromise.future
  }
}

子车才捷
2023-03-14

这就是为什么您很少使用成功失败,除非您已经知道某些东西是防弹的。如果您想要防弹,这就是try的作用:

val producer = future {
  p complete Try( produceSomething )
  continueDoingSomethingUnrelated()
}

似乎没有必要再次抛出错误;你已经通过把它打包到promise的答案里来处理它了,不是吗?(另外,请注意,如果< code>produceSomething本身返回一个未来值,您可以使用< code>completeWith来代替。)

 类似资料:
  • 这是一个有问题的或有更好替代物的 gem 列表。不要在项目中使用它们。 rmagick - 这个 gem 因大量消耗内存而臭名昭著。应使用 minimagick 来替代它。 autotest - 测试自动化的过时方案,远不及 guard 和 watchr。 rcov - 代码覆盖率工具,不兼容 Ruby 1.9。应使用 SimpleCov 来替代它。 therubyracer - 内存杀手,强烈不

  • 尽管支持抢先式多任务处理,但进程生成却很昂贵——虽然比不上 VMS,但是(平均生成一个进程需要0.1秒左右)要比现在的 Unix 高出一个数量级。脚本功能薄弱,操作系统广泛使用二进制文件格式。除了此前我们总结过的,还有这些后果: 大多数程序都不能用脚本调用。程序间依赖复杂脆弱的远程过程调用(RPC)来通信,这是滋生 bug 的温床。 ……………… Unix 的系统配置和用户配置数据分散存放在众多的

  • 本文向大家介绍缺陷报告内容有哪些?相关面试题,主要包含被问及缺陷报告内容有哪些?时的应答技巧和注意事项,需要的朋友参考一下 三部分:基本信息、缺陷主体、跟踪记录 ①基本信息:编号、版本号、软件名称、编译号、测试人员、日期、指定处理人、硬件平台、操作系统、严重程度、优先级 ②缺陷主体:缺陷概述、预置条件、详细描述、预期结果、实际结果 ③跟踪记录:处理报告、处理日期、修改记录、返测人、返测版本、返测日

  • 本文向大家介绍缺陷报告原则有哪些?相关面试题,主要包含被问及缺陷报告原则有哪些?时的应答技巧和注意事项,需要的朋友参考一下 ①Correct(准确):每个组成部分的描述准确,不会引起误解; ②Clear(清晰):每个组成部分的描述清晰,易于理解; ③Concise(简洁):只包含必不可少的信息,不包括任何多余的内容; ④Complete(完整):包含复现该缺陷的完整步骤和其他本质信息; ⑤Cons

  • 本文向大家介绍Apache Kafka的缺陷相关面试题,主要包含被问及Apache Kafka的缺陷时的应答技巧和注意事项,需要的朋友参考一下 答:Kafka的局限性是: 没有完整的监控工具集 消息调整的问题 不支持通配符主题选择 速度问题

  • 缺陷跟踪(Bug Tracking)是软件研发流程中重要的一环,集项目需求管理和缺陷管理于一身,通过对研发工作流的控制帮助团队建立规范的研发体系。GitHub提供轻量级的缺陷跟踪模块,称为Issues。小巧、易用的Issues模块能与Pull Request紧密整合,是Pull Request工作流的有益补充。 一个小型、管理文档和网页的项目,使用Pull Request往往就足够了。试想如果贡献