我想确保我了解如何创建tasklet和asyncrounous方法。我所拥有的是一个返回列表的方法。我希望从某个地方调用它,并立即允许其他调用。所以我有这个:
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)
这段代码是否符合我的期望?也就是说,这两个调用是否会异步运行?我正确使用期货吗?
编辑:经过测试,代码确实会产生预期的结果。我是Python的新手 - 有什么方法可以测试方法是否运行异步?
答案 0 :(得分:4)
很难自己验证方法是否同时运行 - 你必须进行大量的登录。同样在开发应用程序服务器中它会更难,因为它并不真正并行运行RPC。
您的代码看起来没问题,它在正确的位置使用yield
。
我唯一的建议是命名你的函数get_updates_for_user_async()
- 它与NDB本身使用的约定相匹配,并且是对你的代码的读者提示函数返回一个Future并且应该得到以获得实际结果
另一种方法是在map_async()
对象上使用Query
方法;它会让你编写一个只包含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的异步函数的一般略微优化,并立即返回所产生的值。 (如果你没有立即得到这个,你就是一个好公司,并且它有可能被未来的维护者破坏。: - )