如何理解龙卷风gen.coroutine

时间:2013-12-13 02:06:01

标签: python tornado

我只是Tornado的新手而不是Python。

我正在尝试为CouchDB编写异步客户端(使用couchdb包)。

经过1天的研究/谷歌搜索,我发现每个帖子只是简单地使用HttpAsyncClient,而不是告诉为什么以及 gen.coroutine 如何工作。 源代码对我来说太复杂了解装饰器之后的装饰器HttpAsyncClient对我来说是一个不好的例子......

2 个答案:

答案 0 :(得分:0)

坦率地说,对于ma来说,只有在阅读了源代码之后,我才能(部分地)理解逻辑

如果您使用somefunction()装饰tornado.gen

,它会有类似的效果
    声明yield somefunction()中的
  1. 实际上称为somefunction()
  2. 由于它是一个包装器,因此不会执行您的代码,而是tornado.coroutine.gen。它会运行您的代码,直到yield
  3. 中的第一个somefunction
  4. 如果产生了Future(placehodler)(回到装饰器代码!),龙卷风说:“好的,当这个未来结束时,为IOLoop安排一个任务(IOLoop回调),以便它调用一些another_callback()” 。
  5. 为了跟踪somefunction()执行的消失程度,Tornado维护了一个名为Runner的特殊对象。它会记住阻止执行yield的最后一个somefunction()语句,并在执行装饰器gen时首次运行。
  6. 在第3点之后,Future已“注册”,此Runner从其主run()方法返回并且装饰器退出,返回其自己的
  7. 当第3点的Future准备就绪时,它会向IOLoop添加一个任务,然后调用another_callback。 Latter是由Tornado创建的一个特殊回调,很快就会发现,run()与第3点时运行的Runner相同。新解决的Future已经产生了。
  8. Runner使用.send()方法将新解析的Future的值注入您的somefuncion,这会导致ait被分配给函数中的变量(如果有),如同这样:

    a = yield some_other_coroutine_for_example_async_client_fetch()
    
  9. 好的,这是一个要点,有很多deatails,其中一些我不得不包围我的头,尤其是异常处理,但HTH

答案 1 :(得分:0)

第一个答案涵盖了很多。我只是想让你知道一个更简单的抽象。 @ Gen.coroutine

res = yield foo()

协程的想法是异步执行foo(),尤其是当foo需要大量的IO或网络工作时。 产量可能会激活foo()执行并转移控制权,例如,呼叫者。它留下一个Runner来注册这个foo()任务作为未来的obj。然后当foo()成功返回结果时,这是神奇的事情,Runner将以yield语句执行结果的形式发回结果(告诉值yield和yield语句执行结果之间的差异)。