简体   繁体   English

一定时间后如何调用回调函数

[英]how to call a callback function after certain amount of time

I'm using Twisted along with Txmongo lib. 我正在使用Twisted和Txmongo lib。 In the following function, I want to invoke cancelTest() 5 secs later. 在下面的函数中,我想在5秒钟后调用cancelTest()。 But the code does not work. 但是代码不起作用。 How can I make it work? 我该如何运作?

from twisted.internet import task

def diverge(self, d):
    if d == 'Wait':
        self.flag = 1
        # self.timeInit = time.time()
        clock = task.Clock()
        for ip in self.ips:
            if self.factory.dictQueue.get(ip) is not None:
                self.factory.dictQueue[ip].append(self)
            else:
                self.factory.dictQueue[ip] = deque([self])
                # self.factory.dictQueue[ip].append(self)

        log.msg("-----------------the queue after wait")
        log.msg(self.factory.dictQueue)
###############################HERE, this does not work
        self.dtime = task.deferLater(clock, 5, self.printData)
#############################
        self.dtime.addCallback(self.cancelTest)
        self.dtime.addErrback(log.err)
    else:
        self.cancelTimeOut()
        d.addCallback(self.dispatch)
        d.addErrback(log.err)



def sendBackIP(self):
    self.ips.pop(0)
    log.msg("the IPs: %s" % self.ips)

    d = self.factory.service.checkResource(self.ips)

    d.addCallback(self.diverge) ###invoke above function
    log.msg("the result from checkResource: ")
    log.msg()

In general reactor.callLater() is the function you want. 通常, reactor.callLater()是您想要的功能。 So if the function needs to be called 5 seconds later, your code would look like this: 因此,如果需要在5秒后调用该函数,您的代码将如下所示:

from twisted.internet import reactor
reactor.callLater(5, cancelTest)

One thing that is strange is that your task.deferLater implementation should also work. 奇怪的是,您的task.deferLater实现也应该起作用。 However without seeing more of your code I don't think I can help you more other than stating that it's strange :) 但是,在没有看到更多代码的情况下,除了声明它很奇怪之外,我认为我无法提供更多帮助:)

References 参考

you're doing almost everything right; 您几乎在做所有正确的事情; you just didn't get the Clock part correctly. 您只是没有正确获得Clock部分。

twisted.internet.task.Clock is a deterministic implementation of IReactorTime, which is mostly used in unit/integration testing for getting a deterministic output from your code; twisted.internet.task.Clock是IReactorTime的确定性实现,主要用于单元/集成测试中,以从代码中获取确定性输出; you shouldn't use that in production. 您不应该在生产中使用它。

So, what should you use in production? 那么,您应该在生产中使用什么? reactor ! 反应堆 In fact, all production reactor implementations implement the IReactorTime interface. 实际上,所有生产反应堆实施都实现IReactorTime接口。

Just use the following import and function call: 只需使用以下导入和函数调用:

from twisted.internet import reactor
# (omissis)
self.dtime = task.deferLater(reactor, 5, self.printData)

Just some sidenotes: 只是一些旁注:

in your text above the snippet, you say that you want to invoke cancelTest after five seconds, but in the code you actually invoke printData; 在代码段上方的文本中,您说要在五秒钟后调用cancelTest,但是在代码中实际上是调用printData; of course if printData just prints something, doesn't raise and returns an immediate value, this will cause the cancelTest function to be executed immediately after since it's a chained callcack; 当然,如果printData仅打印某些内容,不提高并返回立即数,这将导致cancelTest函数在它被链接的调用后立即执行; but if you want to actually be 100% sure, you should call cancelTest within deferLater, not printData . 但是,如果您确实想100%确定,则应该在deferLater而不是printData中调用cancelTest

Also, I don't understand if this is a kind of "timeout"; 另外,我不知道这是否是一种“超时”; please be advised that such callback will be triggered in all situations, even if the tests take less than five seconds. 请注意,即使测试时间少于五秒钟,也会在所有情况下触发此类回调。 If you need a cancelable task, you should use reactor.callLater directly; 如果您需要可取消的任务,则应直接使用Reactor.callLater; that will NOT return a deferred you can use, but will let you cancel the scheduled call. 不会返回您可以使用的延期服务,但可以让您取消预定的通话。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM