2011-07-31 14 views
2

非同期のOpenWebPage()機能を持つクラスを作成しました。 OpenWebPage(someUrl)に電話すると、ハンドラが呼び出されます(OnPageLoad(reply))。私は、lastActionというグローバル変数を使って、ページがロードされるとハンドラを扱いました。ハンドラはlastActionをチェックし、適切な関数を呼び出します。例:非同期ネットワークコール

this->lastAction == "homepage"; 
this->OpenWebPage("http://www.hardwarebase.net"); 

void OnPageLoad(reply) 
{ 
    if(this->lastAction == "homepage") 
    { 
     this->lastAction = "login"; 
     this->Login();  // POSTs a form and OnPageLoad gets called again 
    } 
    else if(this->lastAction == "login") 
    { 
     this->PostLogin(); // Checks did we log in properly, sets lastAction as new topic and goes to new topic URL 
    } 
    else if(this->lastAction == "new topic") 
    { 
     this->WriteTopic(); // Does some more stuff ... you get the point 
    } 
} 

ここでは、多数の「アクション」があるときを書き留めて把握するのが難しいです。ホームページ、ログイン、新しいトピック:

OpenWebPage("http://hardwarebase.net") // Stores the loaded page HTML in self.page 
OpenWebpage("http://hardwarebase.net/login", {"user": username, "pw": password}) // POSTs a form 
if(self.page == ...): // now do some more checks etc. 
    // do something more 

が、今私がアクションを保持しているキュークラスを持っていることを想像:私は、Pythonで何かをしていた場合(同期)、それは次のように、はるかに簡単でした。非同期コールバックを介して、これらのすべてのアクション(適切な順番で1つずつ)をどのように実行する必要がありますか?最初の例は明らかに完全にハードコードされています。

率直に言って、私はこれが今まで書かれた最悪の問題である恐れているので、私は、あなたが私の質問を理解してほしい:X

P.S.これはすべてQtで行われます。

答えて

1

単一のメンバ変数を使用して、任意の数の非同期操作の状態を維持しようとすると、あらゆる方法でバグを招待します。 OpenWebPageの呼び出し順序を決める方法がないため、特定の操作でいつでもlastActionの値を関連付ける方法もありません。

これを解決する方法はいくつかあり、例えば:インスタンス

  • 戻り進捗状況や店舗追跡OpenWebPageからオブジェクトごとに1ページを処理不変クラスの

    1. カプセル化、ウェブページの読み込み運転者の状態
    2. 火操作が完了した信号と信号
  • 1

    すべての "if"ブランチの末尾に "return"ステートメントを追加する必要があります。コードでは、最初のOnPageLoad呼び出しですべての "if"ブランチが実行されます。

    一般的に、非同期状態の組み合わせは、同期より常に複雑です。 lastAction型を列挙型に置き換えることを検討してください。また、OnPageLoadスレッドコンテキストが任意の場合は、グローバル変数へのアクセスを同期させる必要があります。

    +0

    に操作のコンテキストを添付うん、ええと、それは問題ではない、私が書いていました実際のアプリケーションでは "else if"がありました。 – Ahmed