Python Twisted: «ждать», пока переменная не будет заполнена другим событием - PullRequest
4 голосов
/ 03 сентября 2010

Я знаю, что витая не будет "ждать" ... Я работаю с клиентом XMPP для обмена данными с внешним процессом.Я отправляю запрос и мне нужно получить соответствующий ответ.Я использую sendMessage для отправки моего запроса на сервер.Когда сервер отвечает на метод onMessage, он получает его и проверяет, отвечает ли он на запрос (не обязательно тот, который я ищу), и помещает любой ответ в стек.В качестве возврата к моему sendRequest я хочу вернуть результаты, поэтому я хотел бы получить ответ на мой запрос из стека и вернуться.Я читал о потоках, отложениях, обратных вызовах и условных выражениях, перепробовал много примеров, и ни один из них не работает для меня.Так что мой пример кода очень урезан псевдокодом, чтобы проиллюстрировать мою проблему.Любой совет приветствуется.

class Foo(FooMessageProtocol):
    def __init__(self, *args, **kwargs):
        self.response_stack = dict()
        super(Foo, self).__init__(*args, **kwargs)    


    def sendRequest(self, data):
        self.sendMessage(id, data)
        # I know that this doesn't work, just to illustrate what I would like to do:
        while 1: 
            if self.response_stack.has_key(id):
               break
               return self.response_stack.pop(id) 


    def receiveAnswers(self, msg):
        response = parse(msg)
        self.response_stack[response['id']] = response

1 Ответ

3 голосов
/ 03 сентября 2010

вы не можете вернуть результаты в sendRequest, потому что sendRequest не может ждать.make sendRequest вместо этого возвращает Deferred и запускает его при получении результата.

Таким образом, код, вызывающий sendRequest, может просто добавить обратный вызов к отложенному, и он будет вызван при получении ответа.

Примерно так (псевдокод):

class Foo(FooMessageProtocol):
    def __init__(self, *args, **kwargs):
        self._deferreds = {}
        super(Foo, self).__init__(*args, **kwargs)    

    def sendRequest(self, data):
        self.sendMessage(id, data)
        d = self._deferreds[id] = defer.Deferred()
        return d

    def receiveAnswers(self, msg):
        response = parse(msg)
        id = response['id']
        if id in self._deferreds:
            self._deferreds.pop(id).callback(response)
...