对龙卷风的协程感到困惑

时间:2018-06-21 08:41:43

标签: python tornado coroutine

我正在尝试找出龙卷风的gen.py中流动的代码。

    future = TracebackFuture()
    if replace_callback and 'callback' in kwargs:
        callback = kwargs.pop('callback')
        IOLoop.current().add_future(
            future, lambda future: callback(future.result()))

    try:
        result = func(*args, **kwargs)
    except (Return, StopIteration) as e:
        result = getattr(e, 'value', None)
    except Exception:
        future.set_exc_info(sys.exc_info())
        return future
    else:
        if isinstance(result, types.GeneratorType):
            try:
                orig_stack_contexts = stack_context._state.contexts
                yielded = next(result) # A (mark)
                if stack_context._state.contexts is not orig_stack_contexts:
                    yielded = TracebackFuture()
                    yielded.set_exception(
                        stack_context.StackContextInconsistentError(
                            'stack_context inconsistency (probably caused '
                            'by yield within a "with StackContext" block)'))
            except (StopIteration, Return) as e:
                future.set_result(getattr(e, 'value', None))
            except Exception:
                future.set_exc_info(sys.exc_info())
            else:
                Runner(result, future, yielded)
            try:
                return future
            finally:
                future = None
    future.set_result(result)  # B
    return future

我有两个功能。

@coroutine
def foo():
     #do something
     bar = yield bar()
     #do something else

@coroutine
def bar():
     #do something
     return [1,2,3,4]

然后,调用foo()函数,代码运行到标记为A的位置。将调用函数bar(),并且由于bar()不是GeneratorType,它将像正常函数一样运行。接下来,设置未来结果并返回未来。在返回未来之前设定结果的这一点最令人困惑。在bar()返回未来之后,foo()得到了这个未来,但是在io_loop.add_future处理该未来之前,已经完成了set_result。

感谢您的帮助,谢谢。

1 个答案:

答案 0 :(得分:1)

我对忽略代码非常愚蠢:

if self.handle_yield(first_yielded): 
       self.run() 

如果将来完成,则该值将发送到相应的生成器。