Seltsame Callback-Ausführungsreihenfolge in Twisted?

  • Beachten Sie den folgenden Code:

     from twisted.internet.defer import Deferred
    
    d1 = Deferred()
    d2 = Deferred()
    
    def f1(result):
        print 'f1',
    
    def f2(result):
        print 'f2',
    
    def f3(result):
        print 'f3',
    
    def fd(result):
        return d2
    
    d1.addCallback(f1)
    d1.addCallback(fd)
    d1.addCallback(f3)
    
    #/BLOCK====
    d2.addCallback(f2)
    d1.callback(None)
    #=======BLOCK/
    
    d2.callback(None)
     

    Dies gibt das aus, was ich erwarten würde:

     f1 f2 f3
     

    Wenn ich jedoch die Reihenfolge der Anweisungen in BLOCK auf

    <| tippe >
     #/BLOCK====
    d1.callback(None)
    d2.addCallback(f2)
    #=======BLOCK/
     

    dh Feuer d1 bevor der Rückruf zu d2 hinzugefügt wird, bekomme ich:

     f1 f3 f2
     

    Ich verstehe nicht warum Das Auslösen der Verzögerungen sollte die Callback-Ausführungsreihenfolge beeinflussen.
    Ist dies ein Problem mit Twisted oder ist dies in gewisser Weise sinnvoll?

    22 November 2011
    Jaap Versteegh
1 answer
  • tl; dr - Wenn Sie einen zurückgestellten (d2) von einem Rückruf (fd zurückgeben, wird er in die Rückrufkette des zurückgestellten (d1) calle d fd. Dies geschieht durch Hinzufügen einer Fortsetzung der Callback-Kette von f d1 als Callback o n d2. Wenn Sie also einen Callback hinzufügen, t o d2 nach firin g d1 wird nach d1 s Fortsetzung an angehängt.


    Ich glaube, Sie Es fehlt der Umstand, dass Verzögerungen an und für sich nicht asynchron sind. Sie sind nur eine strukturiertere Methode, um Callbacks und Fehlerbehandlungsroutinen in asynchronem Code zu verketten. Die Callbacks werden zu einem späteren Zeitpunkt nicht mehr aufgerufen. Sie werden als bezeichnet, wenn der verzögerte Befehl ausgelöst wird . Wenn Sie möchten, dass dies später erfolgt, müssen Sie Ihre Anrufe mit a reactor integrieren.

    Vielleicht macht das die Antwort auf diese Frage etwas offensichtlicher:

    Ich kann nicht erkennen, warum der Zeitpunkt des Auslösens der Verzögerungen die Reihenfolge der Callback-Ausführung beeinflussen sollte.

    Wenn Sie die Rückrufe ändern, , nachdem Sie ausgelöst haben, wird die Verzögerung ausgelöst.

    Erläuterung Ihres Codes

    Im ersten Beispiel:

      d1.callback(None) bewirkt, dass s d1 ausgelöst wird f1 wird aufgerufen (druckt "f1") fd wird aufgerufen (return s d2) ol>

      Jetzt hört es auf, denn e d2 wurde in die Rückrufkette eingefügt für r d1 zwischen n f1 und d f3, wurde jedoch noch nicht ausgelöst. Dann ...

        d2.callback(None) s d2 ausgelöst werden f2 wird aufgerufen (druckt "f2") d1 Callback-Kette wird fortgesetzt; s o f3 wird aufgerufen (druckt "f3")

      Im zweiten Beispiel

        d1.callback(None) bewirkt, dass s d1 ausgelöst wird f1 wird aufgerufen (Drucke & # 34
    23 November 2011
    detly