2017-01-25 3 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を削除すると、コードは期待どおりに機能しなくなります。

誰かがこの問題を解決するためにコールバックを使用して説明しましたが、このコンテキストでそれらを使用する方法を理解していません。サイト名は常に最後として表示されていることを

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 

注:私は見コンソールで

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')}); 

} 

がadosanからの提案に基づいてコードを更新しました

EDIT 1つはリストにあります。

+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

このソリューションは、コールバックよりもはるかに優れていますが、非ブロッキングで、必要なコードが少なく、保守が容易です。私が '$ .when.apply($、promiseList).then(function(){/ * SUCCESS * /}、function(){/ * FAILURE * /});を' $ .when.applyと置き換えたときにお返事ありがとう –

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*/}); 

完全なコードはこれのようになります。falseに設定する:

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

{console.log( 'fail'}); '、私は10のサイトを持っていますが、そのうちの1つが失敗するはずです。 'ネットワークモニタ'で期待通りに各サイトを参照してくださいが、コンソールには1つの '失敗'が含まれています。 –

+0

リストからテストの壊れたサイトを削除すると、このメソッドは、すべてのサイトが有効な値を返す場合にのみ動作するように思われます。ステータスに応じてリスト内の各サイトに対してアクションを実行する必要があります。成功または失敗など –

+0

インナーエラー:function(data){console.log(sites [i] .url + "failed。)"というエラーハンドラをコードに追加する必要があります。 } – adosan