2011-03-21 95 views
1

我有以下代碼,我想異步運行,但日誌顯示它們正在同步運行。JQuery AJAX請求表現爲同步不明原因

$(".widget").each(function() { 
    // snip - url, def, and tempParams defined here 
$.ajax({ 
    url: url, 
    dataType: "jsonp", 
    type: "POST", 
    data: {params: tempParams}, 
    success: function(data) { 
     var st = new Date().getTime(); 
     console.error("Start " + def.name + " @" + st); 
     doSomething(data); 
     var et = new Date().getTime(); 
     console.error("End " + def.name + " @" + et); 
     console.error("Duration " + def.name + " " + (et-st) + " ms."); 
    } 
}); 

控制檯輸出清楚地顯示了成功職能,以便執行,而不是異步:

Start f1 @1300738891705 
End f1 @1300738891744 
Duration f1 39 ms. 
Start f2 @1300738892746 
End f2 @1300738893280 
Duration f2 534 ms. 
Start f3 @1300738893282 
End f3 @1300738893303 
Duration f3 21 ms. 
Start f4 @1300738893305 
End f4 @1300738893306 
Duration f4 1 ms. 
Start f5 @1300738893484 
End f5 @1300738895609 
Duration f5 2125 ms. 

的思考?我覺得這一定是我忽略的事情。

回答

1

我認爲你們都混淆了這兩個術語。就AJAX而言是異步的,因此JQuery意味着HTTP請求消息將被髮送到網絡服務器,而不會在客戶端造成任何延遲。這些請求很可能會順序發送到服務器,但我不認爲這是有保證的。我認爲你在考慮線程...

同步調用可能導致客戶端延遲,而瀏覽器的JavaScript解釋器正在等待AJAX​​響應。

想一想一個簡單的例子,可以說你有一個AJAX調用來獲取美國州的稅率。如果它是一個同步調用,那麼結賬工具將停止計算,並且任何與Javascript的用戶交互都不會產生響應,直到收到AJAX響應(與稅率)。

在上面的異步情況下,您可以定義一個回調函數,一旦收到AJAX響應,它將繼續計算最終結帳價格。

+0

我知道這是愚蠢的。我在ajax調用之外添加了調試代碼(就像我應該做的那樣),它們確實是異步執行的。我正在想象他們會在他們自己的線程中執行,這導致了我對錯誤的理解。感謝您清理東西! – 2011-03-21 21:01:07

1

調試輸出全部來自success函數,該函數在請求完成並且結果到達後被調用。即使這些請求是異步完成的,結果也會在他們進來時被一個接一個地處理。

在您的示例中,您可能會啓動五個請求,這些請求在後臺同步運行(異步)。第一個結果進入後,瀏覽器會調用第一個函數success,該函數爲您提供f1函數的調試輸出。完成此處理後,瀏覽器會查看是否同時完成了更多請求,並繼續爲這些請求調用success函數。

ajax請求的結果可能與您請求的順序相同,以便您按順序獲取日誌消息。但是也有可能一個請求需要更長的時間,例如在f3之前得到的日誌輸出爲f4,因爲結果要早得多。

+0

你是完全正確的 - 我只是在ajax調用之前添加了控制檯輸出,他們確實以不同於發送的順序返回,所以它們實際上表現爲異步。我的問題似乎是,鎖定某些作業成功的UI將產生請求阻止的印象。 – 2011-03-21 20:59:33

1

試試這個...

var st = new Date().getTime(); 
console.error("Start " + def.name + " @" + st); 
$.ajax({ 
    url: url, 
    dataType: "jsonp", 
    type: "POST", 
    data: {params: tempParams}, 
    success: function(data) { 
     doSomething(data); 
     var et = new Date().getTime(); 
     console.error("End " + def.name + " @" + et); 
     console.error("Duration " + def.name + " " + (et-st) + " ms."); 
    } 
}); 
0

我相信,通過觀察MGM並行執行的實際問題一直被忽視 becuse他進行時間記錄爲「成功」功能的一部分。 他對asyn進行了一般性解釋。請求的性質作爲答案,然而, 這裏有一個問題。

看看下面的代碼片段:

$(function() { 
     $(".dd").each(function() { 
      var obj = $(this); 
      $.get("test.txt", function(data) { 
       obj.html(data); 
      }); 
     }); 
    }); 

它加載一個文件(異步我所期望的),並將其顯示(同步的課程)。

但是,在首次加載頁面和刷新頁面時,代碼的執行方式不同。 我在Windows上使用Firefox 4.0中的Firebug Net面板監視對服務器的請求。 在第一頁加載時(或使用Ctrl-F5刷新時),我可以在網絡面板 上看到多個請求「test.txt」同時啓動,網絡活動主要覆蓋。

該零件按預期工作。結果可能會在瀏覽器中逐一處理, ,但對服務器的請求是並行執行的。

(圖像:初始負荷) (http://i.stack.imgur.com/nSFld.gif)

它是完全地不同故事whne用戶按下F5刷新頁面。突然間的並行性消失了。
同樣的網頁一個接一個加載「test.txt」。

(圖像:後續刷新) (http://i.stack.imgur.com/7cYfM.gif) 如果我替換數據顯示它變得更加清晰(obj.html(數據))用簡單警報:警報(數據); 在初始頁面加載時,我同時在屏幕上顯示多條警報消息。 後續刷新(F5)清楚地表明,雖然屏幕上有一條警報消息,但沒有其他 下載被執行(我可以刪除文件以查看「$ .get」失敗)。

所以實際上$ .get不執行異步。調用服務器。

關於爲什麼會發生這種情況的任何想法?

P.S. 對不起系統不允許我發佈圖片。