代码之家  ›  专栏  ›  技术社区  ›  Liviu

龙卷风协程从另一个协程逐渐产生

  •  0
  • Liviu  · 技术社区  · 6 年前

    我想重构Tornado应用程序的一部分,因此我创建了一个返回电话号码的特殊功能:

    @gen.coroutine
    def get_phones(self, listname):
        phones = []
        logging.info("fetching phones")
        cursor = self._mongo.contacts.aggregate(self.get_query(
            subscription_filter={
                "$ne": [{"$ifNull": ["$$subscription.events.{listname}", None]}, None]
            },
            handler_filter={
                "handler.meta.is_active": True,
                "handler.meta.type": "phone"
            }
        ))
        try:
            while (yield cursor.fetch_next):
                contact = cursor.next_object()
                logging.info(contact)
                try:
                    phones += [handler['subject'] for handler in contact['handlers']]
                    if len(phones) > 50:
                        yield phones
                        phones = []
                except Exception:
                    self._logger.warning("Could not get phone no")
        except Exception:
            phones = []
            logging.warning("Could not fetch contacts")
    
        if len(phones) > 0:
            yield phones
    

    我想用它来实现的是从我的数据库中异步获取最多50个联系人的批,并将它们返回到调用coroutine。

    这是我的合奏:

    @gen.coroutine
    def on_heartbeat_status_update(self, status):
        phonegen = self.get_phones("ews:admin")
        logging.info(phonegen)
        while True:
            phones = yield phonegen
            logging.info(phones)
            if phones is None:
                break
            logging.info(len(phones))
    

    它不起作用。”“电话”总是没有。有人能提出实现这一目标的正确方法吗?谢谢!

    1 回复  |  直到 6 年前
        1
  •  0
  •   Ben Darnell    6 年前

    您必须使用Python3.6本机协程才能正常工作。这是python的第一个版本,它同时支持 yield await 在同一个函数中。如果没有这个,系统就无法区分使用 产量 作为一个生成器产生一个结果。

    替换 @gen.coroutine def 具有 async def 使用 await cursor.fetch_next yield phones 在里面 get_phones . 那你就可以用 async for phones in self.get_phones(...) 在里面 on_heartbeat_status_update .