对tornado的协程不解
Puzzled about the coroutine of tornado
我正在尝试找出龙卷风 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,它将运行 就像一个正常的功能。接下来,设置未来结果和 return 未来。在 return future 之前设置结果的这一点是最令人困惑的。在 bar()
return 未来之后,foo()
得到这个未来,但是未来在 io_loop.add_future
处理之前已经 set_result 完成了。
任何帮助将不胜感激,在此先感谢。
我太蠢了,竟然忽略了代码:
if self.handle_yield(first_yielded):
self.run()
如果future完成了,这个值会被发送到对应的generator。
我正在尝试找出龙卷风 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,它将运行 就像一个正常的功能。接下来,设置未来结果和 return 未来。在 return future 之前设置结果的这一点是最令人困惑的。在 bar()
return 未来之后,foo()
得到这个未来,但是未来在 io_loop.add_future
处理之前已经 set_result 完成了。
任何帮助将不胜感激,在此先感谢。
我太蠢了,竟然忽略了代码:
if self.handle_yield(first_yielded):
self.run()
如果future完成了,这个值会被发送到对应的generator。