<p>坦白地说,对马来说,只有在读了《源》之后,我才(部分地)理解了其中的逻辑</p>
<p>如果你用<code>tornado.gen</code>装饰<code>somefunction()</code>,它的工作原理是这样的:</p>
<ol>
<li>在语句<code>yield somefunction()</code>中,实际调用了somefunction()</li>
<li>因为它是一个包装器,所以执行的不是您的代码而是<code>tornado.coroutine.gen</code>。它运行您的代码,直到<code>somefunction</code>中的第一个<code>yield</code></li>
<li>如果一个Future(placehodler)被产生(回到decorator代码!),tornado说:“好吧,当这个未来解决时,为IOLoop安排一个任务(IOLoop回调),以便它调用一些<code>another_callback()</code>”。在</li>
<li>为了跟踪您的<code>somefunction()</code>的执行过程,Tornado维护了一个名为<code>Runner</code>的特殊对象。它记住最后一条<code>yield</code>语句,该语句阻止了<code>somefunction()</code>的执行,并在执行装饰器<code>gen</code>时首次运行。在</li>
<li>在第3点之后,Future被“注册”,这个运行器从它的主<code>run()</code>方法返回,decorator退出,返回自己的Future</li>
<li>当未来从第三点开始。准备就绪后,它向IOLoop添加一个任务,IOLoop随后调用<code>another_callback</code>。后者是Tornado创建的一个特殊回调,简单地说,它与在第3点运行时运行的相同。一个新解决的未来产生了。在</li>
<li><p>Runner使用<code>.send()</code>方法将一个新解析的Future值注入到<code>somefuncion</code>中,这会导致ait被分配给函数in语句中的一个变量(如果有):</p>
<pre><code>a = yield some_other_coroutine_for_example_async_client_fetch()
</code></pre></li>
</ol>
<p>好吧,这是一个要点,这里有很多细节,其中一些我无法完全理解,尤其是异常处理,但是</p>