2010-11-03 101 views
2

如果頁面上的表單當前正在提交,我有一個競爭條件,我不希望發生AJAX調用。有沒有辦法知道HTML表單當前正在提交?

我寧願不改變表單的代碼。

我正在考慮將事件處理程序附加到每個表單元素,以便onsubmit它會增加一個計數器,然後onreadystatechange遞減計數器。

然後在AJAX調用之前,請檢查以確保計數器在觸發前爲零。

但有更簡單的方法,如(僞代碼):

form.isSubmitting 

編輯:

競爭狀態,因爲每說JavaScript的不是。這是由服務器端響應這些操作的順序而發生的。

爲了讓您更廣泛問題的一個想法:

設置cookie的形式後返回時。 在AJAX調用中(需要每隔X秒發生一次)...服務器端(如果表單發生了)期望cookie被設置。

有時....

如果在表單提交返回(並設置cookie客戶端)的延遲,觸發AJAX調用不發送的cookie回來。

服務器期望cookie,因爲就其而言表單發佈已成功。

但是,我需要控制客戶端以確保按照規定的方式執行操作。

所以正確的JavaScript本身不會導致競爭條件,但(就我測試顯示的那樣) - 提交和返回POST/AJAX調用導致競爭條件在我的特定情況下。

回答

1

在網頁上,Javascript中沒有「競爭條件」,因爲只有一個執行線程。如果您希望在表單提交後(或在任何時候)阻止事件處理程序執行任何操作,最簡單的方法是設置一些全局訪問標誌。處理程序例程必須檢查。當然,在適當的時候標記被清除是很重要的。

編輯 —確定你的編輯之後,這是一個更加清楚一點,你在做什麼,但有一點是不明確的:被究竟怎麼貼在表格?這是一個「自然」的形式嗎?如果是這樣的話,整個頁面將被響應重新加載。或許目標是單獨的?

或者說是形式提交的一些其他AJAX代碼?

  1. 如果表單提交的「自然」的瀏覽器,我們正在談論的是整個頁面被重新裝入,那麼這可能是最簡單的情況。表單的「提交」處理程序應該簡單地設置全局標誌,並且通過間隔計時器運行的代碼應該在設置標誌時間隔上不做任何事情。無需擔心清除標誌,因爲無論如何頁面都會被響應炸燬。

  2. 如果窗體頁面上的內發佈,或張貼到隱藏,那麼它幾乎相同的(1),除了響應頁面需要明確的全局標誌。究竟如何做到這一點取決於何種應用設置涉及,但基本上只會是一些JavaScript在設置top.postingFlagfalse(或其他)的響應。

  3. 如果它是單獨發佈表單的AJAX代碼,那麼您在啓動XMLHttpRequest時設置標誌,並在處理程序中清除它以獲得成功/失敗。

在所有情況下,關鍵在於間隔計時器中的代碼監視標誌的狀態,並避免在設置標誌時發佈。

+0

沒有的setInterval()允許多個線程同時運行? – Jez 2010-11-03 14:30:44

+0

否 - 每次定時程序被調用時,它就像從一個按鈕點擊事件循環 - 它永遠不會在任何種類的另一事件循環的中間發生 – Pointy 2010-11-03 14:43:53

+0

現代「網絡工作者」其實辦法有多個線程,但他們從其他代碼「防火牆」很好,所以你仍然不能有競爭條件 – Pointy 2010-11-03 14:44:32

0

是的,這是可行的。

您可以通過一個AJAX調用提交表單。通過這種方式,您可以控制ajaxSendajaxComplete事件,並具有用作標誌的全局變量var formIsSubmiting = false

就在非表單AJAX調用之前檢查變量的狀態,並且應該阻止您的競爭條件

1

您可以添加給表單標籤:

<form ... onsubmit="this.setAttribute('isSubmitting', 'true');"> 

你就可以看它是否通過檢查屬性「提交」。

相關問題