1

我想确保我知道如何创建 tasklet 和异步方法。我所拥有的是一个返回列表的方法。我希望从某个地方调用它,并立即允许进行其他调用。所以我有这个:

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 的新手 - 有哪些方法可以测试这些方法是否正在异步运行?

4

1 回答 1

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装饰器并仅返回由以下方式返回的 Future来进一步简化此操作map_async()

def get_updates_for_user_Async(userKey, lastSyncDate):
  noteQuery = ndb.gql('...')
  return noteQuery.map_async(lambda note: note.to_dict())

这是对仅包含一个 yield 并立即返回所产生值的异步函数的一般轻微优化。(如果你没有立即得到这个,那么你就是一个很好的公司,并且它冒着被未来的维护者破坏的风险。:-)

于 2012-08-27T01:21:10.843 回答