如果您查看 Future 的实现,它与 python 中的生成器非常相似。事实上,它使用相同的yield
关键字来实现它所说的功能。阅读tasklets.py 上的介绍性评论以获得一些说明。
当您使用 @tasklet 装饰器时,它会创建一个 Future 并等待包装函数上的值。如果该值是一个生成器,它会将 Future 添加到事件循环中。当您yield
使用 Future 时,事件循环会运行所有排队的 Future,直到您想要的 Future 准备好。这里的并发性是每个 Future 都将执行其代码,直到它返回(使用raise ndb.Return(...)
或函数完成)、抛出异常或yield
再次使用。我想从技术上讲,您可以yield
在代码中使用来停止执行该函数,以让事件循环继续运行其他期货,但我认为这不会有太大帮助,除非您真的有一个聪明的用例。
要回答您的问题:
技术上是的,但它不会异步运行。当你用@tasklet 装饰一个非屈服函数时,它的Future 值会在你调用该函数时计算和设置。也就是说,当你调用它时,它会贯穿整个函数。如果要实现异步操作,就必须yield
在做异步工作的东西上。通常在 GAE 中,它会一直运行到 RPC 调用。
如果通过在您的 PC 上工作,您的意思是开发应用服务器是否实现了类似 GAE 的 tasklets/Futures,那么是的,尽管这对于 devappserver2(现在是较新 SDK 中的默认设置)更为准确。实际上,我不是 100% 确定本地 RPC 调用是否会在使用 Futures 时并行运行,但是无论是本地还是生产中,都有一个通过 Futures 的事件循环。如果你想在你的其他非 GAE 代码中使用 Future,那么我认为你最好使用Python 3.2 的内置 future(或者在这里找到一个 backport)
有点,这不是一个简单的比较。在此处查看文档。想法有些相同(调度器可以比作事件循环),但低级实现有很大不同。