如何产生 gen.coroutine 方法

how to yield gen.coroutine methods

我是 运行 Tornado 服务器,具有以下 class:

class SessionHandler(tornado.websocket.WebSocketHandler):
   def open(self):
      pass

   def on_close(self):
      pass

   @tornado.gen.coroutine
   def on_message(self,message):
      #db added to the tornado application object on init
      self.application.db.add("test")
      x=self.application.db.get("test")
      print(x)

获取函数如下(数据库class的一部分):

   @tornado.gen.coroutine
   def get(self,key):
      result=[]
      lookup=yield self.postCol.find_one({"_id":key})

      if not lookup:
         return result

      for id in lookup["FieldArray"]:
         ob=yield self.postCol.find_one({"_id":ObjectId(id)})
         result.append(ob)
      return result

我不会输入 add() 函数。

我意识到 get() return 是一个 Future 对象而不是 数组 。很好,我意识到我需要将我的代码更改为 x = yield self.application.db.get("test")

我的问题是 add() 函数在我的方法中没有明确的 return 值?

当我也调用它时,我还需要 yieldyield self.application.db.add("test")?

它目前确实可以在我不屈服的情况下工作,但是我想知道 notyield 是否是一个错误,因为我知道return 是 Future 对象吗?

如果是这样,是否意味着我基本上必须 yield 我调用的任何装饰有 gen.coroutine[=45= 的方法]?

是的,您应该 "yield" 对协程的任何调用。有两个原因:

  1. 如果您不让步,则会生成协程并与调用协程同时运行。您可能想等待 "add" 完成后再执行 "on_message" 中的下一条语句?让 "on_message" 等待 "add" 完成的唯一方法是产生 "add".
  2. 返回的 Future
  3. 如果 "add" 抛出异常——例如,如果您与数据库的网络连接失败,或者如果您的文档无效或违反了唯一索引——知道抛出异常的唯一方法是产生 "add" 返回的 Future。否则异常会被忽略,见 the big warning in Tornado's coroutine documentation.