1

最初に申し訳ありませんが、テキストの壁。Twisted および非同期プログラミング全般を理解するのに苦労しています。

Twisted 15.4.0 で Python 2.7 を使用しています。

この例を downloadPage() で試してみましたが、完全に機能します。

コールバックをラムダから適切な関数に変更して、少しいじりました。出来た。また、reactor.stop() ステートメントをコールバックとエラーバックの両方から削除しようとしましたが、唯一の効果は、ダウンロード後にスクリプトが停止しないことです。イベントループがまだ実行されているため、これは理にかなっています。

また、壊れた URL を指定してみました。

downloadPage() への呼び出しが 1 つしかない場合、プログラムはブロックされます。エラーバックは発生しません。

2 つの呼び出しがあり、1 つは壊れた URL で、もう 1 つは正しい URL である場合、呼び出しが実行され、終了し、コールバックが起動され (正しいものと仮定します)、終了します。

私の最初の質問は、なぜこれが起こるのですか? 壊れた URL に対してエラーバックが発生しないのはなぜですか? 壊れた URL でエラーが発生するべきではありませんか?


次のような別のコードがあります。

def receive_some_data():
   # Do some non twisted stuff - The script runs and passes these lines
   While True:
       try:
           # Do some other non twisted stuff
           print "1"
           downloadPage("http//:www.google.com", "foo").addCallbacks(
               lambda value:(println('Good'),reactor.stop()),
               lambda error:(println("an error occurred",error),reactor.stop()))
           print "2"
       except Exceptions as e:
           print str(e)

def main():
    reactor.callWhenRunning(receive_some_data)
    reactor.run()

このコードは機能しません。「1」と「2」が出力されますが、コールバックやエラーバックの呼び出しはありません。また、ページは「foo」にダウンロードされません。

2 番目の質問は、このコードが機能しないのはなぜですか? While ループのせいでしょうか。もしそうなら、while ループは deferred とそのコールバック チェーンにどのように影響しますか?


編集 1:「While True」を 3 回の反復後に終了する「While 条件」に変更しました。ファイルがダウンロードされ、コールバックが呼び出されます。無限ループがダウンロードを妨げているのはなぜですか?

また、While ループ内の「# Do some other non twisted stuff」行は、パイプからの読み取りを実行します。ここで URL を取得します。

URL を継続的に読み取り、ダウンロードが完了した瞬間にコールバックをスケジュールする最善の方法は何ですか?


編集 2:コードを次のように変更しました。

def receive_some_data():
    # Do some non twisted stuff
    if condition:
        # Request more urls
        downloadPage(url,file).addCallbacks(success,fail)
    else:
        # Ask sender not to send urls atm

def main():
    reactor.callWhenRunning(receive_some_data)
    reactor.run()

コードの構造を、callWhenRunning() が receive_some_data 関数を呼び出し続ける (無限ループのように) という考え方に変更しました。そうではありません。

この関数を呼び出し続けるイベントループを取得するにはどうすればよいですか?


編集3:これを何とか機能させることができました。Looping Callメソッドについて知りました。Looping Call を使用して x 秒ごとにEdit 2からコードを呼び出します。できます。他の方法はありますか?


ありがとう!

4

1 に答える 1

2

基本的に、複数回呼び出しているときに行っていることは、downloadPage複数のダウンロードを並行して開始することです。最初に終了したものは、そのコールバックまたはエラーバックを呼び出す最初のものになり、それによってリアクターが停止し、他のすべてのダウンロードが停止します。

そのため、1 つの呼び出しの URL を不適切なホストに変更すると、リクエストがタイムアウトするまでに時間がかかります。それまでに、他の (正常な) ダウンロードが完了し、リアクターを停止します。これが、コードが 1 つの適切な URL でのみ機能する理由です。

while他の例では、ダウンロードを次々と作成し、関数から戻りませんreceive_some_data。ただし、ダウンロードの呼び出し/エラーバックを実行できるようにするには、戻る必要があります。Twisted は一度に 1 つの呼び出しのみを実行します。

于 2015-12-01T14:06:28.897 に答える