如何从返回的延迟实例中获取值
how to get value from returned instance of deferred
我使用 txmongo 库作为 mongoDB 的驱动程序。
在其有限的文档中,txmongo 中的 find 函数将 return 一个 deferred 实例,但我怎样才能得到实际结果(如 {"IP":11.12.59.119})?我尝试了 yield、str() 和 repr() 但没有用。
def checkResource(self, resource):
""" use the message to inquire database
then set the result to a ip variable
"""
d = self.units.find({'$and': [{'baseIP':resource},{'status':'free'}]},limit=1,fields={'_id':False,'baseIP':True})
#Here above, how can I retrieve the result in this deferred instance??
d.addCallback(self.handleReturnedValue)
d.addErrback(log.err)
return d
def handleReturnedValue(self, returned):
for ip in returned:
if ip is not None:
d = self.updateData(ip,'busy')
return d
else:
return "NA"
如果你想在 Twisted 中编写看起来更像同步的异步代码,请尝试使用 defer.inlineCallbacks
Consider the following function written in the traditional Deferred
style:
def getUsers():
d = makeRequest("GET", "/users")
d.addCallback(json.loads)
return d
using inlineCallbacks, we can write this as:
from twisted.internet.defer import inlineCallbacks, returnValue
@inlineCallbacks
def getUsers(self):
responseBody = yield makeRequest("GET", "/users")
returnValue(json.loads(responseBody))
编辑:
from twisted.internet.defer import inlineCallbacks, returnValue
@inlineCallbacks
def checkResource(self, resource):
""" use the message to inquire database
then set the result to a ip variable
"""
returned = yield self.units.find({'$and': [{'baseIP':resource},{'status':'free'}]},limit=1,fields={'_id':False,'baseIP':True})
# replacing callback function
for ip in returned:
if ip is not None:
d = self.updateData(ip,'busy') # if this returns deferred use yield again
returnValue(d)
returnValue("NA")
如果您想从 deferred 中获取实际值,可以在结果可用后进行。需要多长时间才能可用取决于它在等待什么。
看看下面的例子。在结果可用之前有任意 2 秒的延迟,因此在此之前尝试访问它会抛出 AttributeError
from twisted.internet import defer, reactor
def getDummyData(inputData):
"""
This function is a dummy which simulates a delayed result and
returns a Deferred which will fire with that result. Don't try too
hard to understand this.
From Twisted docs
"""
deferred = defer.Deferred()
# simulate a delayed result by asking the reactor to fire the
# Deferred in 2 seconds time with the result inputData * 3
reactor.callLater(2, deferred.callback, inputData * 3)
return deferred
d = getDummyData(2)
reactor.callLater(1, lambda: print(d))
# Prints: <Deferred at 0x7f4853ed3550>
reactor.callLater(3, lambda: print(d))
# Prints: <Deferred at 0x7f4853ed3550 current result: 6>
reactor.callLater(3, lambda: print(d.result))
# Prints: 6
# Throws AttributeError because Deferred does not have a result after 1 sec
# reactor.callLater(1, lambda: print(d.result))
reactor.callLater(4, reactor.stop)
reactor.run()
我使用 txmongo 库作为 mongoDB 的驱动程序。 在其有限的文档中,txmongo 中的 find 函数将 return 一个 deferred 实例,但我怎样才能得到实际结果(如 {"IP":11.12.59.119})?我尝试了 yield、str() 和 repr() 但没有用。
def checkResource(self, resource):
""" use the message to inquire database
then set the result to a ip variable
"""
d = self.units.find({'$and': [{'baseIP':resource},{'status':'free'}]},limit=1,fields={'_id':False,'baseIP':True})
#Here above, how can I retrieve the result in this deferred instance??
d.addCallback(self.handleReturnedValue)
d.addErrback(log.err)
return d
def handleReturnedValue(self, returned):
for ip in returned:
if ip is not None:
d = self.updateData(ip,'busy')
return d
else:
return "NA"
如果你想在 Twisted 中编写看起来更像同步的异步代码,请尝试使用 defer.inlineCallbacks
Consider the following function written in the traditional Deferred style:
def getUsers():
d = makeRequest("GET", "/users")
d.addCallback(json.loads)
return d
using inlineCallbacks, we can write this as:
from twisted.internet.defer import inlineCallbacks, returnValue
@inlineCallbacks
def getUsers(self):
responseBody = yield makeRequest("GET", "/users")
returnValue(json.loads(responseBody))
编辑:
from twisted.internet.defer import inlineCallbacks, returnValue
@inlineCallbacks
def checkResource(self, resource):
""" use the message to inquire database
then set the result to a ip variable
"""
returned = yield self.units.find({'$and': [{'baseIP':resource},{'status':'free'}]},limit=1,fields={'_id':False,'baseIP':True})
# replacing callback function
for ip in returned:
if ip is not None:
d = self.updateData(ip,'busy') # if this returns deferred use yield again
returnValue(d)
returnValue("NA")
如果您想从 deferred 中获取实际值,可以在结果可用后进行。需要多长时间才能可用取决于它在等待什么。
看看下面的例子。在结果可用之前有任意 2 秒的延迟,因此在此之前尝试访问它会抛出 AttributeError
from twisted.internet import defer, reactor
def getDummyData(inputData):
"""
This function is a dummy which simulates a delayed result and
returns a Deferred which will fire with that result. Don't try too
hard to understand this.
From Twisted docs
"""
deferred = defer.Deferred()
# simulate a delayed result by asking the reactor to fire the
# Deferred in 2 seconds time with the result inputData * 3
reactor.callLater(2, deferred.callback, inputData * 3)
return deferred
d = getDummyData(2)
reactor.callLater(1, lambda: print(d))
# Prints: <Deferred at 0x7f4853ed3550>
reactor.callLater(3, lambda: print(d))
# Prints: <Deferred at 0x7f4853ed3550 current result: 6>
reactor.callLater(3, lambda: print(d.result))
# Prints: 6
# Throws AttributeError because Deferred does not have a result after 1 sec
# reactor.callLater(1, lambda: print(d.result))
reactor.callLater(4, reactor.stop)
reactor.run()