Using inlineCallbacks

拥有回忆 提交于 2019-12-01 15:16:17

问题


I'm new to Twisted and I'm trying to write a simple resource which displays a list of names from a database, here's a part of my code:

#code from my ContactResource class
def render_GET(self, request):
    def print_contacts(contacts, request):
        for c in contacts:
            request.write(c.name)
        if not request.finished:
            request.finish()
    d = Contact.find() #Contact is a Twistar DBObject subclass
    d.addCallback(print_contacts, request)
    return NOT_DONE_YET

My question is: how can I change this method to use the inlineCallbacks decorator?


回答1:


A render_GET method may not return a Deferred. It may only return a string or NOT_DONE_YET. Any method decorated with inlineCallbacks will return a Deferred. So, you may not decorate render_GET with inlineCallbacks.

Of course, nothing stops you from calling any other function you want in render_GET, including one that returns a Deferred. Just throw the Deferred away instead of returning it from render_GET (of course, make sure that the Deferred never fires with a failure, or by throwing it away you may be missing some error reporting...).

So, for example:

@inlineCallbacks
def _renderContacts(self, request):
    contacts = yield Contact.find() 
    for c in contacts:
        request.write(c.name)
    if not request.finished:
        request.finish()


def render_GET(self, request):
    self._renderContacts(request)
    return NOT_DONE_YET

I recommend at least taking a look at txyoga and klein if you're going to be doing any serious web development with Twisted. Even if you don't want to use them, they should give you some good ideas about how you can structure your code and accomplish various common tasks like this one.




回答2:


Edit: I didn't find an example how to combine twisted.web with inlineCallbacks, but here are two suggestions. The first is preferable, but I'm not sure if it works.

@inlineCallbacks
def render_GET(self, request):
    contacts = yield Contact.find() 
    defer.returnValue(''.join(c.name for c in contacts)


@inlineCallbacks
def render_GET(self, request):
    contacts = yield Contact.find() 
    for c in contacts:
        request.write(c.name)
    if not request.finished:
        request.finish()
    defer.returnValue(NOT_DONE_YET)


来源:https://stackoverflow.com/questions/14712752/using-inlinecallbacks

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!