Python Twisted:“等待”用于由另一个事件填充变量

发布于 2024-09-16 21:05:58 字数 884 浏览 6 评论 0原文

我知道twisted不会“等待”...我正在使用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

I know that twisted will not "wait"... I am working with an XMPP client to exchange data with an external process. I send an request and need to fetch the corresponding answer. I use a sendMessage to send my request to the server. When the server answers a onMessage method will receive it and check if it an answer to a request (not necessarily the one I am looking for) and puts any answer in a stack.
As return to my sendRequest I want to return the results, so I would like to pop the response to my request from the stack and return.
I read about threads, defers, callbacks and conditionals, tried a lot of the examples and none is working for me. So my example code here is very stripped down pseudo-code to illustrate my problem. Any advice is appreciated.

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

比忠 2024-09-23 21:05:58

您无法将结果返回给 sendRequest,因为 sendRequest 等不及。
sendRequest 返回一个 Deferred ,并在结果到达时触发它。

因此,调用 sendRequest 的代码只需向 deferred 添加一个回调,当有响应时就会调用它。

像这样的东西(伪代码):

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)

you can't return the results to sendRequest, because sendRequest can't wait.
make sendRequest return a Deferred instead, and fire it when the result arrives.

So the code calling sendRequest can just add a callback to the deferred and it will be called when there's a response.

Something like this (pseudo-code):

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)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文