什么之间的区别Future
,并Promise
?
他们都像对未来业绩的占位符,但如果是主要的区别?
Answer 1:
根据这一讨论 , Promise
终于被称为CompletableFuture
包含在Java的8,和它的javadoc解释说:
甲未来可明确地完成(设定其值和状态),并且可以被用作CompletionStage,支持有关的功能和它的完成时触发动作。
一个例子也给出了名单上:
f.then((s -> aStringFunction(s)).thenAsync(s -> ...);
需要注意的是最后的API略有不同,但允许类似的异步执行:
CompletableFuture<String> f = ...;
f.thenApply(this::modifyString).thenAccept(System.out::println);
Answer 2:
(我不是答案完全满意为止,所以这里是我的尝试......)
我认为凯文·怀特的评论(“你可以做出承诺,它是给你保留它。当别人让你的承诺,你必须等待,看看他们是否履行它在未来”),总结了它不错,但有些解释可能是有用的。
期货和承诺是相当类似的概念,不同的是,未来对于那些尚不存在的结果只读容器,同时承诺可以写成(通常只有一次)。 Java的8 CompletableFuture和番石榴SettableFuture可以被认为是承诺,因为他们的值可以设置(“已完成”),但他们也实现了Future接口,因此有客户端没有差别。
未来的结果将被“别人”设置 - 通过异步计算的结果。 注意如何FutureTask -一个经典的未来- 必须有一个Callable或Runnable的初始化,没有无参数的构造函数,两者未来FutureTask是只读的从外部(FutureTask的设定方法保护)。 该值将被设置为从内部计算的结果。
在另一方面,承诺的结果可以用“您”(或事实上任何人)任何时候,因为它有一个公共的setter方法设置。 无论CompletableFuture和SettableFuture可以在没有任何任务创建,其价值可以在任何时间进行设置。 你发送一个承诺客户端代码,并且希望以后完成它。
需要注意的是CompletableFuture不是一个“纯粹”的承诺,它可以与就像FutureTask任务进行初始化,其最有用的功能是处理步骤无关的链接。
还要注意的是一个承诺并不一定是未来的一个亚型,它不必是同一个对象。 Scala中的一个未来的目的是通过异步计算或由不同的无极对象创建的。 在C ++中的情况是类似的:承诺对象由生产者和消费者对未来的对象。 这种分离的好处是,客户端不能设置未来的价值。
两个弹簧和EJB 3.1具有AsyncResult类,它是类似于斯卡拉/ C ++承诺。 AsyncResult确实实现的未来,但这不是真正的未来:春异步方法/ EJB通过一些背景魔术返回不同的,只读的Future对象,而这第二个“真正的”未来能够被客户用来访问结果。
Answer 3:
据我所知,已经有一个公认的答案,但希望仍然添加我的两分钱:
TLDR:未来的承诺是一个异步操作的两个方面: 消费/主叫方与制片人/实施者 。
作为一个异步API方法的调用者 ,你会得到一个Future
的句柄计算的结果。 您可以如呼叫get()
就可以了,等待计算完成并检索结果。
现在想这个API方法是如何实际实现: 实现者必须返回一个Future
马上。 他们负责只要计算完成(他们会知道,因为它是实现分派逻辑;-))完成未来。 他们将使用一个Promise
/ CompletableFuture
来做到这一点:构建并返回CompletableFuture
立即,并调用complete(T result)
一旦计算完成。
Answer 4:
我会给出什么承诺,以及如何它的价值可以在任何时候进行设置,在对面的未来,其值仅可读一个例子。
假设你有一个妈妈,你问她要钱。
现在,你欺骗你的妈妈为你创造最终捐款的承诺,她给你这个承诺的对象,但她是不是真的皮疹履行它尚未:
Supplier<Integer> momsPurse = ()-> {
try {
Thread.sleep(1000);//mom is busy
} catch (InterruptedException e) {
;
}
return 100;
};
ExecutorService ex = Executors.newFixedThreadPool(10);
CompletableFuture<Integer> promise =
CompletableFuture.supplyAsync(momsPurse, ex);
你快乐时,你跑谢谢你的妈妈:
promise.thenAccept(u->System.out.println("Thank you mom for $" + u ));
但是,你的父亲干涉,一般中止妈妈的计划和完成的承诺(它的值设置!)远用较小的贡献,作为父亲做的,很坚决,而妈妈被缓缓地开口了她的钱包(注意了Thread.sleep(...)):
promise.complete(10);
那输出为:
Thank you mom for $10
妈妈的承诺是创造,但等待一些“完成”事件。
CompletableFuture<Integer> promise...
你创造了这样的事件,接受她的承诺,并宣布自己的计划来感谢你的妈妈:
promise.thenAccept...
这时的妈妈开始打开她的钱包......但很慢...
和父亲干涉更快,完成了承诺,而不是你的妈妈:
promise.complete(10);
你有没有注意到,我写了明确的执行? 有趣的是,如果使用默认的隐式的执行者,而不是(commonPool)和父亲不在家,只有她的“慢钱包”妈妈,然后她承诺将只完成,如果节目生活的时间比妈妈需要从拿钱钱包。 我的意思是在“守护程序”的方式默认执行行为。 我还没有发现这个事实很好的说明...
Answer 5:
不知道这可能是一个答案,但我看到其他人所说的人它可能看起来像你需要这两个概念的两个独立抽象性,因此他们中的一个( Future
)就是其他的只读视图( Promise
)......但实际上,这是没有必要的。
例如看一看承诺是如何在JavaScript中定义:
https://promisesaplus.com/
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise
重点是使用可组合then
方法等:
asyncOp1()
.then(function(op1Result){
// do something
return asyncOp2();
})
.then(function(op2Result){
// do something more
return asyncOp3();
})
.then(function(op3Result){
// do something even more
return syncOp4(op3Result);
})
...
.then(function(result){
console.log(result);
})
.catch(function(error){
console.log(error);
})
这使得异步计算看起来像同步:
try {
op1Result = syncOp1();
// do something
op1Result = syncOp2();
// do something more
op3Result = syncOp3();
// do something even more
syncOp4(op3Result);
...
console.log(result);
} catch(error) {
console.log(error);
}
这是很酷。 (数据不作清凉如异步-等待但异步-等待只是删除了样板....然后(函数(结果){....从它)。
而实际上他们的抽象是作为承诺的构造相当不错
new Promise( function(resolve, reject) { /* do it */ } );
让您提供可用于或者完成两个回调Promise
成功还是有错误。 因此,只有那些构建代码Promise
可以完成,并接收已构建的代码Promise
对象具有只读视图。
随着继承以上,如果能够实现的决心和拒绝是受保护的方法。
Answer 6:
在未来的接口没有设置方法,只有get方法,所以它是只读的。 关于CompletableFuture,这篇文章也许有帮助。 completablefuture
Answer 7:
对于客户端的代码,无极是观察或附加回调时,结果是可用的,而未来是等待结果,然后继续。 从理论上讲任何事情是可能的,期货是什么可以做承诺做的,但由于风格的差异,不同语言的承诺产生的API使链接更容易。