2014-04-19 36 views
0

我已經搜索了高和低的替代品(承諾,異步調用等),但還沒有找到一個可行的解決方案。如何在不支持時使用超時實現javascript同步xmlhttprequest?

我有這樣一個相當典型的情況:

blockingCallBackFunctionFor3rdPartyLibraryAPI(url) 
{ 
    responseCode = cloudLookupCall(url); // async or sync call over the web 
    if (responseCode == "Deny") 
    { 
     // Return "Deny" URL decision to external library/API 
    } 

    // Return default "Allow" decision 
} 

function cloudLookupCall(url) 
{ 
    var hdl = new XMLHttpRequest(); 
    hdl.open(method, url, true/false); // true/false based on async/sync 

    // use standard XHR stuff to get responseText 
    return responseText; 
} 

現在:

  1. 如果我使用異步與承諾要求,回調什麼的,我還需要一些決定重返第三方庫因爲a)JS不支持睡眠/等待,b)我不能使用異步onload()中的回調,因爲那時第三方API已經移到其他URL上
  2. 如果我改用SYNC電話我冒着被封鎖的風險無限期。我已經在Web雲處理程序上使用超時,因此它不會花太長時間並處理onerror(),但仍擔心同步調用可能會持續太久。

我只是不明白爲什麼JS實現決定不支持同步調用超時時,這正是您最需要它的地方(以避免永久掛起瀏覽器)。

我已經閱讀了大量的論壇迴應,其中提出了Promise和異步回調 - 但請注意上述爲什麼這些不起作用 - 我需要一個行動逃走或者我需要一種方法讓JS等待。我不能等,也不會回覆一個行動。

在這一點上,我相當確信我堅持使用SYNC調用,但是看看最新技術的狀態是如何確保它不會永久阻止(而ASYNC不是另一種選擇)。確保我的web php處理程序在1秒內使用set_time_limit()超時解決無限期懸掛問題?

+0

是'cloudLookupCall'是你創造出來的?您可能需要將該函數定義(減少到基本內容)添加到您的問題中。 –

+0

您可以使用同步呼叫,並事先使用'setTimeout'設置默認消息出現之前的最大延遲? – Lugia101101

+0

@TimVermaelen現在增加了瘦身定義。 – user1952627

回答

0

如果可能嘗試將function作爲參數添加到cloudLookupCall()

function cloudLookupCall(func){ 
    // your stuff here 

    // and when it's needed for you to callback 
    if (typeof func === 'function'){ 
     func(); 
    } 
} 

然後在你的腳本:

responseCode = cloudLookupCall(function(data){ 
    // continue here 
}); 

如果不工作,這是一個包裝我作爲備份使用當回調或承諾不可用,我需要使用功能回退:

// @param (callback): function to be run when done 
// @param (delay): integer in milliseconds 
// @param (id): string value of a unique event id 
delayedEvent: (function() { 
    var timers = {}, 
     defEvent = cfg.events; 

    return function (callback, delay, id) { 
     delay = delay || 1000; 
     id = id || 'some id'; 

     if (timers[id]) { 
      clearTimeout(timers[id]); 
     } 

     timers[id] = setTimeout(callback, delay); 
    }; 
})(), 

您可以使用它像這樣:

responseCode = cloudLookupCall(); 

delayedEvent(function(){ 
    if (responseCode === "Deny"){ 
     // continue here 
    } 
}, 1000, 'cloudlookup'); 
+0

在第一種方法中,「// continue here」會將控制權返回給第三方API,並將轉到其他URL。 – user1952627

相關問題