2014-12-19 108 views
0

當用戶在我的應用程序上按下'Process'按鈕時,我希望應用程序觸發AJAX請求,然後立即將用戶重定向到另一個屏幕而無需等待AJAX​​的結果請求。我相信我已經編寫了適當的代碼,但我注意到屏幕正在等待AJAX​​在重定向之前完成。我錯過了什麼?Javascript不會異步超越AJAX調用

$('#process-btn').on('click', function() 
{ 
    // disable the process & cancel buttons to prevent 
    // double submission or interruption 
    $('#cancel-btn').addClass('disabled'); 
    $(this).addClass('disabled'); 

    // trigger the AJAX require to process the uploaded file on the server side 
    $.ajax({ 
     url: $('#form').attr('action'), 
     type: 'post', 
     data: $('#form').serialize(), 
     success: function() { 
      //on success 
     } 
    }); 

    // redirect the user to view list 
    // this line is not being called immediately - 
    // this is being called only after AJAX returns 
    window.location.replace(www_root + 'Home/index'); 
}); 
+0

您是否在ajax設置中設置了'async:false' ...嘗試在ajax選項中設置'async:true'並參見 – 2014-12-19 04:07:01

+0

爲什麼不包含'window.location.replace(www_root +'Home/index ');'在ajax成功函數中?既然你想根據成功結果重定向。 – Aditya 2014-12-19 04:08:12

+0

如果您希望在成功之前離開頁面,那麼擁有「成功」塊有什麼意義? – Verhaeren 2014-12-19 04:08:15

回答

0

因爲你有這樣的處理程序掛接到該按鈕是一個表單提交按鈕(按你的意見),你不會阻止的默認行爲該按鈕,然後表單提交將立即發生,當提交返回時,無論您的代碼嘗試做什麼,它都會更改頁面。

所以,問題是返回的表單提交是克服你的代碼試圖做什麼。


在您的ajax調用完成之前,您可能通過重定向而生活有點危險。在TCP緩衝區實際發送之前,瀏覽器可能會丟棄ajax連接,因爲TCP在發送緩衝區之前通常會有一個小的延遲,以便將連續的數據收集到公共數據包中。在短暫超時後重定向或重定向complete事件將更加安全,無論Ajax成功,將被調用。


如果你真的想要做的重定向之前Ajax調用完成後,您可以使用超時值實驗代碼(在這裏顯示爲設置爲500毫秒),看看在多個瀏覽器工作可靠:

$('#process-btn').on('click', function(e) { 
    // prevent default form post 
    e.preventDefault(); 

    // disable the process & cancel buttons to prevent 
    // double submission or interruption 
    $('#cancel-btn').addClass('disabled'); 
    $(this).addClass('disabled'); 

    // trigger the AJAX require to process the uploaded file on the server side 
    $.post($('#form').attr('action'), $('#form').serialize()); 

    // redirect the user to view list 
    // this being called after a short delay to "try" 
    // to get the form ajax call sent, but not "wait" for the server response 
    setTimeout(function() { 
     window.location.replace(www_root + 'Home/index'); 
    }, 500); 
}); 

而且,我已經添加了一個e.preventDefault(),並添加了e參數到事件處理程序以確保表單默認情況下不貼了,只有你的Ajax代碼註釋。

而且,超時時間在此設置爲500ms。您需要足夠的時間讓主機中的TCP基礎結構在開始重定向之前發送所有表單數據。我在您的評論中看到提及「文件上傳」。如果這個表單實際上傳了一個文件,那可能會超過500ms。如果只是發送一些表單字段,假設沒有連接打嗝,那應該會很快。

警告:這樣做並不是100%可靠的獲取數據到服務器的方式。在連接服務器或服務器之前,可能需要比通常的時間更長的時間進行DNS查找,或者在將數據發送到服務器之前,可能需要較長的時間才能響應初始連接。唯一100%可靠的方法是等到ajax調用成功後再提到其他地方。

如果您改變了服務器處理ajax調用的方式,並且一旦它接收到數據,它就會返回成功的響應(例如以毫秒爲單位),您也許可以兩全其美(可靠性+快速響應)在收到數據後),然後在它發送回成功的響應之後,瀏覽器可以可靠地重定向,實際處理數據需要2-3分鐘。請記住,您不會等待處理請求才能返回響應。然後,您知道服務器已收到數據,但瀏覽器無需等待處理時間。如果你不總是希望這個Ajax調用以這種方式工作,你可以傳遞一個參數給ajax調用來指示服務器是否需要快速響應。

+0

賓果!將其從提交按鈕更改爲常規按鈕,並立即發生重定向。 – ChicagoSky 2014-12-19 04:24:05

+1

這可能是評論部分的評論。 – 2014-12-19 04:24:37

+0

@MangeshParte - 這是答案。我們在各種評論中發現了這一點,然後我發佈了這個答案。 – jfriend00 2014-12-19 04:27:01

-2

爲什麼不試試這個:

$.ajax({ 
     url: $('#form').attr('action'), 
     type: 'post', 
     data: $('#form').serialize(), 
     success: function() {window.location.replace(www_root + 'Home/index');} 
    }); 
+1

我嚴重懷疑這個作品。 – Aditya 2014-12-19 04:13:35

+0

在ajax調用開始之前會調用'window.location.replace(...)',可能會阻止它啓動。你需要傳遞一個函數引用,而不是像'success:function(){window.location.replace(...)}'執行'window.location.replace(...)'的返回結果。 – jfriend00 2014-12-19 04:13:38

+0

@ jfriend00可能會給出錯誤 – 2014-12-19 04:14:26