2017-01-25 3 views
0

Я бег функции под названием checker каждых 60 секунд, как так:Multiple AJAX вызовов без блокировки

setInterval(checker, 60 * 1000); 

checker имеет множество URL-адреса, которые утилита проверяет с помощью AJAX, текущий код выглядит так:

$.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. Моя проблема в том, что время выполнения этой проверки нескольких сайтов составляет ~ 4 секунды, после чего страница перестает отвечать на запросы. Если я удалю async: false, код больше не работает должным образом.

Кто-то упоминает использование обратных вызовов для решения проблемы, но не понимает, как их использовать в этом контексте.

EDIT

Обновленный код, основанный на предложении от 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

Я бы попробовал этот.

Давайте предположим, что объект, который вы хотите быть в курсе является вар 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 ($, promList) .then (function() {/ * SUCCESS * /}, function() {/ * FAILURE * /});' с '$ .when.apply ($, promList) .then (function() {console.log ('success')}, function() {console.log ('fail'}); ', у меня есть 10 сайтов, один из которых должен завершиться ошибкой. см. каждый сайт, как ожидалось, в «сетевом мониторе», но консоль содержит один «сбой», никаких успехов для тех, которые работают. –

+0

Если я удалю тестовый сломанный сайт из списка, тогда я получаю «успех», , поэтому этот метод работает только в том случае, если все сайты возвращают рабочее значение. Мне нужно иметь возможность выполнять действие для каждого сайта в списке в зависимости от его статуса, например, успех или сбой. –

+0

Паритетное обещание не срабатывает, если какой-либо из внутренних Если вы хотите обнаружить неисправный сайт в своем коде, вы также должны добавить обработчик ошибок к вашему вызову ajax: error: function (data) {console.log (сайты [i] .url + "не удалось.") } – adosan

Смежные вопросы