一旦有了协程,就可以创建管道(haskell:管道,管道; python:生成器)或协作事件循环(python:curio)。一旦有了期货,看来您可以做同样的事情。管道(rust:Futures-rs)和事件循环(rust:tokio)。由于期货不合作,因此它们需要基于回调的调度程序(甚至基于轮询的期货也需要回调)调度程序来执行线程或进程池中的阻塞任务。像这些语言一样,将期货(库级)与协程(语言级)结合起来有什么好处:(python:asyncio),(rust:rfc),(ecmascript 6+)。从根本上说,它们似乎对同一问题有矛盾的解决方案。
我不是要进行利弊比较,也不赞成期货是“一次性”协程的说法。看看rust,它仅使用Future构建了一个完整的基于状态机的事件框架。我想知道为什么python / asyncio和javascript都需要协程和期货。为什么生锈计划在其期货中添加协程?它与事件的可组合性有关吗?还是协程的隐式堆栈与连续通过的期货的显式堆栈?我不是完全理解这种说法,因为期货和协程都是使用延续实现的?或者它与直接还是间接样式有关?
答案 0 :(得分:1)
这些都是具有不同力量的不同(尽管相关)的想法。
未来是一种抽象,它使您可以开始一个过程,然后在完成该过程后退回到由原始调用方选择的处理程序。
发电机比将来的功能更强大,因为它可以产生多次。您可以在生成器之上实现期货。
协程比生成器更强大,因为它可以选择向谁屈服,而不仅限于呼叫者。例如,它可以产生另一个协程。您可以在协程之上实现生成器。
当功能更强大的工具可用时,为什么还要使用功能较弱的工具?有时,功能较弱的工具是完成工作的正确工具。使用类型对程序的不变式进行静态编码很有用,因为它可以使您确定不能可以做什么。
例如,当对远程服务器进行REST调用时,将来可能就足够了。如果REST客户端公开了一个生成器,那么即使您知道只会有一个结果,您也必须处理它可能产生多次的可能性。如果它暴露了一个协程,则您必须查阅文档以准确确定应如何与之交互—即使您实际上只需要做一件事,这在处理未来时很明显