作为 Python 的新手,我发现 yield 和 generators 以及 async 函数非常令人不知所措(我已经阅读了关于该主题的所有 SO 问题和其他几个不同的引用资料 - 仍然很难将所有部分联系起来)。我已经习惯了 Objective-C 的描述性语法,其中所有内容都只是告诉您它在做什么,而不是试图将您并不真正知道它们如何协同工作的所有不同关键字片段连接起来。
我真的很喜欢 Python,因为它很容易上手 - 至少在基本的事情上是这样。但是对于更高级的东西,代码只是不告诉你。它不会告诉你它在做什么。 (好吧,也许我只是有点沮丧和缺乏经验。)
无论如何,我想让下面的函数完全异步:
@ndb.tasklet
def get_new_statues(friends):
status_list = list()
for friend_dic in friends:
lastStatusDate = #some date
userKey = #some key
query = ndb.gql('SELECT * FROM Statuses WHERE ANCESTOR IS :1 AND date > :2', userKey, lastStatusDate)
qit = query.iter()
while (yield qit.has_next_async()):
status = qit.next()
status_list.append(status.to_dict())
raise ndb.Return(status_list)
当我写这篇文章时,我对自己印象深刻,并且很高兴我能够在短短几个小时内将我所有的代码转换为异步。但是I'm being told上面的函数根本不是异步的。但是然后 in another question我被告知是的,我所做的是正确的。
那么到底是怎么回事呢?此处的 yield 语句是否使我的代码同步?我将如何修改它以使其异步?
(我问的问题看起来都很相似,但问题是我得到了更多的代码作为答案而不是解释。我是一个寻找可以帮助我理解代码的词来理解的人,而不是一台寻找更多代码来帮助我理解更多代码的机器。每个人都只是告诉我如何或什么,没有人告诉我为什么。)
附录:我想最让我失望的是:while (yield qit.has_next_async()): 作为人类读者,我读了这些话yield,在您对这个词的典型用法中,它的意思是“如果有必要,让其他东西做其他事情”,我看到 async 这个词,它很好地意味着异步。所以我想到了 yield + async = 异步方法的神奇公式,但显然情况并非如此?
请您参考如下方法:
听起来你不明白 yield 的作用。
虽然这可能不完全准确,但您通常可以将“yield”视为“return”,除非您再次调用此函数时,它会从上次 yield 的位置继续运行,而不是函数的开头。
由于qit.has_next_async()是异步的,所以这个函数是异步的。每次调用此函数时,它都会返回 qit.has_next_function() 的值,并获取下一个实体。完成后,它会引发异常结果。
