7

文档

NDB tasklet 是一段可能与其他代码同时运行的代码。如果您编写一个 tasklet,您的应用程序可以像使用异步 NDB 函数一样使用它:它调用返回 Future 的 tasklet;稍后,调用 Future 的 get_result() 方法得到结果。

文档中的解释和示例对我来说真的很神奇。我可以使用它,但很难正确理解它。

例如:

  1. 我可以在函数中放入任何类型的代码并将其装饰为 ndb.tasklet 吗?然后稍后将其用作异步功能。还是一定是appengine RPC?
  2. 这种装饰器是否也适用于我的电脑?
  3. 和pypy的tasklet一样吗
4

1 回答 1

15

如果您查看 Future 的实现,它与 python 中的生成器非常相似。事实上,它使用相同的yield关键字来实现它所说的功能。阅读tasklets.py 上的介绍性评论以获得一些说明。

当您使用 @tasklet 装饰器时,它会创建一个 Future 并等待包装函数上的值。如果该值是一个生成器,它会将 Future 添加到事件循环中。当您yield使用 Future 时,事件循环会运行所有排队的 Future,直到您想要的 Future 准备好。这里的并发性是每个 Future 都将执行其代码,直到它返回(使用raise ndb.Return(...)或函数完成)、抛出异常或yield再次使用。我想从技术上讲,您可以yield在代码中使用来停止执行该函数,以让事件循环继续运行其他期货,但我认为这不会有太大帮助,除非您真的有一个聪明的用例。

要回答您的问题:

  1. 技术上是的,但它不会异步运行。当你用@tasklet 装饰一个非屈服函数时,它的Future 值会在你调用该函数时计算和设置。也就是说,当你调用它时,它会贯穿整个函数。如果要实现异步操作,就必须yield在做异步工作的东西上。通常在 GAE 中,它会一直运行到 RPC 调用。

  2. 如果通过在您的 PC 上工作,您的意思是开发应用服务器是否实现了类似 GAE 的 tasklets/Futures,那么是的,尽管这对于 devappserver2(现在是较新 SDK 中的默认设置)更为准确。实际上,我不是 100% 确定本地 RPC 调用是否会在使用 Futures 时并行运行,但是无论是本地还是生产中,都有一个通过 Futures 的事件循环。如果你想在你的其他非 GAE 代码中使用 Future,那么我认为你最好使用Python 3.2 的内置 future(或者在这里找到一个 backport

  3. 有点,这不是一个简单的比较。在此处查看文档。想法有些相同(调度器可以比作事件循环),但低级实现有很大不同。

于 2013-04-06T18:32:49.663 回答