2014-10-20 56 views
0

我試圖通過阻塞一段時間,然後在AJAX返回中翻轉一個標誌來模擬同步ajax調用。但即使達到了時間限制,標誌也不會更新。相反,瀏覽器只是掛起。我已經在Firefox和Safari中測試過相同的結果。超時無法更改在循環中使用的標誌

破碎設計:

function syncAjax(args, timeLimit) { 

    var obj = {}, 
     outOfTime = false, 
     timeout, k, 
     response = {returned: false, failed: false, responseText: null}; 

    timeout = window.setTimeout(function() { 
     outOfTime = true; 
    }, timeLimit); 
    for(k in args) { 
     if(args.hasOwnProperty(k)) { 
      obj[k] = args[k]; 
     } 
    } 
    obj.success = function(responseText) { 
     window.clearTimeout(timeout); 
     response.returned = true; 
     response.responseText = responseText; 
    }; 
    obj.failure = function() { 
     window.clearTimeout(timeout); 
     response.returned = true; 
     response.failed = true; 
    }; 
    // obj["async"] = true; // (automatically async) 
    $.ajax(obj); 
    // insert spinner timeout 
    while(true) { 
     if(response.returned || outOfTime) break; 
    } 
    return response; 

} 

使用範例:

function doIt() { 

    var response = syncAjax({ 
     url: "webpage.php", 
     data: {x: 5}, 
    }, 500); 
    if(!response.returned) { 
     // do time out stuff 
    } else if(response.failed) { 
     // do failed stuff 
    } else { 
     console.log(response.responseText); 
     // do success stuff with response.responseText 
    } 

} 

// !! executing this function will lock up your browser !! 
// doIt(); 
+0

你認爲JavaScript使用多線程? – 2014-10-20 19:14:34

+0

@Garr我認爲超時是在主線程的不同線程中執行的。 – 2014-10-20 19:24:07

+0

不在任何主要瀏覽器中。 javascript沒有任何線程安全工具,比如信號量,所以如果它是多線程的話會有很多問題。 – 2014-10-20 22:55:30

回答

1

JavaScript不能打電話給你的超時時間,直到你從你的函數返回。 setTimeout不是一個線程調用。

你可以爲你的循環做到這一點:

var start = Date().getTime(); 
while(start+timeLimit > Date().getTime()) ; 
+0

當然。謝謝,我認爲這將起作用。 – 2014-10-20 19:25:17