我想确保我了解如何创建微线程和异步方法。我拥有的是一个返回列表的方法。我希望从某个地方调用它,并立即允许进行其他调用。所以我有这个:
future_1 = get_updates_for_user(userKey, aDate)
future_2 = get_updates_for_user(anotherUserKey, aDate)
somelist.extend(future_1)
somelist.extend(future_2)
....
@ndb.tasklet
def get_updates_for_user(userKey, lastSyncDate):
noteQuery = ndb.GqlQuery('SELECT * FROM Comments WHERE ANCESTOR IS :1 AND modifiedDate > :2', userKey, lastSyncDate)
note_list = list()
qit = noteQuery.iter()
while (yield qit.has_next_async()):
note = qit.next()
noteDic = note.to_dict()
note_list.append(noteDic)
raise ndb.Return(note_list)
这段代码是否符合我的预期?也就是说,这两个调用会异步运行吗?我正确使用 future 吗?
编辑:经过测试,代码确实产生了预期的结果。我是 Python 新手 - 有哪些方法可以测试方法是否异步运行?
最佳答案
自己验证这些方法是否同时运行是非常困难的——您必须进行大量的日志记录。而且在开发应用程序服务器中,这会更加困难,因为它并没有真正并行运行 RPC。
您的代码看起来不错,它在正确的位置使用了 yield
。
我唯一的建议是将你的函数命名为 get_updates_for_user_async()
——它与 NDB 本身使用的约定相匹配,并提示代码的读者该函数返回一个 Future 并且应该产生以获得实际结果。
执行此操作的另一种方法是在 Query
对象上使用 map_async()
方法;它可以让您编写一个仅包含 to_dict()
调用的回调:
@ndb.tasklet
def get_updates_for_user_async(userKey, lastSyncDate):
noteQuery = ndb.gql('...')
note_list = yield noteQuery.map_async(lambda note: note.to_dict())
raise ndb.Return(note_list)
高级提示:您可以通过删除 @ndb.tasklet
装饰器并仅返回 map_async()
返回的 Future 来进一步简化:
def get_updates_for_user_Async(userKey, lastSyncDate):
noteQuery = ndb.gql('...')
return noteQuery.map_async(lambda note: note.to_dict())
这是对仅包含一个 yield 并立即返回所产生的值的异步函数的一般轻微优化。 (如果你没有立即明白这一点,那么你就处于良好的伙伴关系中,并且它存在被 future 的维护者破坏的风险,而他也没有这样做。:-)
关于python - 使用 Google App Engine 的 NDB 创建异步方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12125342/