2017-01-25 21 views
0

我運行名爲像checker每60秒這樣的函數調用:多AJAX而不阻斷

setInterval(checker, 60 * 1000); 

checker具有它通過AJAX檢查URL的陣列,當前碼是這樣的:

$.ajax({ 
    url: sites[i].url, 
    type: "GET", 
    dataType: "json", 
    async: false, 
    success: function(data){ 
    //blah blah blah 
    }else{ 
    //something else 
    }, 
    error: function(){ 
    //blah blah blah 
    } 
}); 

代碼工作,根據JSON的結果改變一些基於UI的東西。我的問題是,檢查多個站點的執行時間約爲4秒,此時該頁面此時無響應。如果我刪除async: false代碼不再按預期工作。

有人提到使用回調來解決問題,但不明白如何在這種情況下使用它們。

編輯

從adosan根據建議

更新代碼:

function promtest(){ 
    var sites = [ 
      { name: "WorkingSite", url: "http://sitename.com/testing.php" }, 
      //a bunch more sites, 1 returns a 404 to test for failure 
      { name: "404Site", url: "http://404url.com/testing.php" } 
      ]; 

    var promiseList = []; 
    for(var i in sites){ 
    var promise = $.ajax({ 
    url: sites[i].url, 
    type: "GET", 
    dataType: "json", 
    async: true, 
    success: function(data){ 

     if(data.Response != 'OK'){ 
     console.log('Site ' + sites[i].name + ' Not OK'); 
     }else{ 
     console.log('Site ' + sites[i].name + ' OK '); 
     } 
    }, 

    failure: function(data){ 
     console.log('Failure for site: ' + sites[i].name); 
    }, 

    error: function(){ 
     console.log('Site ' + sites[i].name + ' Not OK'); 
    } 

    }); 

    promiseList.push(promise); 
    } 

    $.when.apply($, promiseList).then(function(){console.log('success')}, function(){console.log('fail')}); 

} 

在控制檯中我看到:

Site 404Site Not OK 
Site 404Site Not OK 
Site 404Site Not OK 
Site 404Site Not OK 
Site 404Site Not OK 
Site 404Site Not OK 
Site 404Site Not OK 
fail 
Site 404Site Not OK 
Site 404Site Not OK 
Site 404Site Not OK 
Site 404Site Not OK 

注意,網站名稱是始終顯示爲最後一個在名單上。

+0

請詳細說明一下,當你刪除異步什麼是不工作:假的設置。 –

+0

你有沒有考慮過異步運行(''async:true'')? – Crowes

+0

我不認爲上面的代碼真的有效...... * else *在函數之外。 – Robert

回答

2

您可以在這裏使用Promise(https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Promise)。例如:

function checker(url) { 
    return new window.Promise(function (resolve, reject) { 

     function successCallback(response) { 
      resolve(response); 
     } 

     function errorCallback(response) { 
      reject(response); 
     } 

     $.ajax({ 
      data: data, 
      dataType: 'JSON', 
      type: 'GET', 
      url: url 
     }) 
     .done(successCallback) 
     .fail(errorCallback); 
    }); 
} 

function checkerSuccess(response) { 
    console.log(response); 
} 

function checkerError(error) { 
    console.warn(error); 
} 

checker('http://api.example.com').then(checkerSuccess).catch(checkerError); 
+0

這看起來很有前途,非雙關意圖,讓我檢查一下。 –

+0

這個解決方案比回調要好得多,同時也是非阻塞的,需要的代碼少,可維護性更好。謝謝 –

0

我會試試這個。

假設要被更新的對象是VAR FOO:

var foo = ""; 

$.ajax({ 
     url: sites[i].url, 
     type: "GET", 
     dataType: "json", 
     async: false, 
     success: function(data){ 

      foo = data.gottenValue1 

     }else{ 
     //something else 
     }, 
     error: function(){ 
     //blah blah blah 
     } 
    }); 
1

您可以使用jQuery內置遞延機制(承諾)。

https://api.jquery.com/category/deferred-object/

jQuery.ajax函數確實返回其可以asigned給一個變量一個承諾對象。

https://api.jquery.com/jQuery.ajax/

var promise = $.ajax({ 
     url: sites[i].url, 
     type: "GET", 
     dataType: "json", 
     async: true 
    }); 

有關承諾的好處是,你可以多promisses合併成更大的。

var promiseList = []; 
promiseList.push(promise); 
$.when.apply($, promiseList).then(function(){/*SUCCESS*/}, function(){/*FAILURE*/}); 

完整的代碼應該看起來像這樣:

var promiseList = []; 
for(var i in sites){ 
    var promise = $.ajax({ 
     url: sites[i].url, 
     type: "GET", 
     dataType: "json", 
     async: true 
    }); 

    promiseList.push(promise); 
} 
$.when.apply($, promiseList).then(function(){/*SUCCESS*/}, function(){/*FAILURE*/}); 
+0

當我替換'$ .when.apply($,promiseList).then(function(){/ * SUCCESS * /},function(){/ * FAILURE * /});''用'.when.apply ($,promiseList).then(function(){console.log('success')},function(){console.log('fail'});',我有10個站點,其中一個應該失敗。在'網絡監視器'中查看每個站點的返回情況,但控制檯包含單個「失敗」,沒有成功的工作。 –

+0

如果我從列表中刪除測試損壞的站點,然後我得到'成功' ,所以這種方法似乎只適用於所有站點返回工作值的情況下,我需要能夠根據列表中的每個站點的狀態執行一個操作,例如成功或失敗 –

+0

如果任何內部如果你想在你的代碼中檢測失敗的站點,你還應該添加錯誤處理程序到你的ajax調用中:error:function(data){console.log(sites [i] .url +「has failed。」) } – adosan