2011-07-31 78 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 
    } 
} 

現在,這是很難寫和跟蹤我們有什麼大量的「行動」。當我在Python做的東西(同步)容易得多,如:網頁,登錄新的話題:

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 

現在我有持有該動作隊列類想象。我應該如何通過異步回調執行所有這些操作(按照正確的順序,一個接一個!)?第一個例子顯然是完全硬編碼的。

我希望你明白我的問題,因爲坦率地說我擔心這是有史以來最嚴重的問題:X

附:所有這些都是在Qt中完成的。

回答

1

如果您嘗試使用單個成員變量來維護任意數量的異步操作的狀態,那麼您正在邀請各種錯誤,這是您在上面描述的內容。您無法確定OpenWebPage調用完成的訂單,因此無法在任何給定時間將lastAction的值與任何特定操作相關聯。

有許多的方式來解決這個問題,比如:在處理每個實例

  • 返回從OpenWebPage對象跟蹤進度和存儲一個頁面的不可變類

    1. 包封物網頁加載操作的狀態
    2. 消防操作何時完成,並附上運行的背景下信號
  • 1

    您需要在每個「if」分支的末尾添加「return」語句:在您的代碼中,所有「if」分支在第一次OnPageLoad調用中執行。

    通常,異步狀態mamangment總是比較複雜的同步。考慮用枚舉替換lastAction類型。另外,如果OnPageLoad線程上下文是任意的,則需要同步對全局變量的訪問。

    +0

    呀,嗯一個信號,這不是一個問題,我在寫僞代碼在這裏,而在真正的應用程序中有「其他如果」。 – Ahmed