Запустить функцию для нескольких значений в массиве в Javascript / AJAX - PullRequest
0 голосов
/ 23 октября 2018

Я запускаю функцию, которая добавляет содержимое переменной в URL-адрес внутри функции:

var stateWarn = "MA";  //variable to be passed (easy to find and change if I want)

$(window).on('load', function() {
  CheckWarnings();
  setInterval(function(){ CheckWarnings(); }, REFRESH_FREQ);
});

function CheckWarnings() {
  arrayEvents = [];
  console.log("Checking API...");
  $.ajax({
      url: 'https://api.weather.gov/alerts/active/area/' + item,
      jsonp: false,
      type: 'get',
      jsonpCallback: 'callback',
      cache: true,
      mode: 'no-cors',
      dataType: 'json',
      crossDomain: true,
      success: function(data) {
        if (data === null) {
          console.log("Data returning with NULL!");
          LoadError();
          return;
        }
        dataTime = data.updated;
        if (!dataTimeCheck) {
          console.log("No check available...creating dataTimeCheck variable 
                      and running jsonCrawler.")
          dataTimeCheck = dataTime;
          console.log("Setting initial datatimeCheck variable to: " + 
          dataTimeCheck);
          jsonCrawler(data);
        } else if (!(dataTime == dataTimeCheck)) {
          console.log("'data' and 'dataTimeCheck' variables do not match... 
          running jsonCrawler.")
          dataTimeCheck = dataTime;
          jsonCrawler(data);
        } else if (dataTime == dataTimeCheck) {
        console.log("No new data detected.")
        return;
      }
      return;

Я хотел бы изменить переменную stateWarn на массив:

var stateWarn = ["MA", "NH", "NY", "RI"]

и запустите функцию CheckWarnings для каждой записи в stateWarn .До сих пор мне не повезло найти способ сделать это с AJAX, который работает для меня.Я сделал это с помощью команды Javascript .forEach.Любая помощь высоко ценится!

Ответы [ 2 ]

0 голосов
/ 23 октября 2018

Я думаю, что вы имеете в виду разницу между синхронными и асинхронными операциями.Для этого погодного API, для получения информации о предупреждениях в определенном географическом регионе area, обычно существует два формата.


Параметры строки запроса:

Сначала я опишу более простую, поскольку это фактически позволит вам сделать это с минимальными изменениями в коде.По сути, вместо выполнения /alerts/active/area/NY вы передаете область в качестве параметра строки запроса.То есть что-то вроде: api.mysite.com/catPics?age=12&breed=sphinx&height=10ft будет означать «доступ к маршруту catPics с age из 12, breed из сфинкса и height из 10 футов. Вы можете сделать это здесь:

const stateWarn = ["MA", "NH", "NY", "RI"];//i'm changing this to a const. better practice!

//for conciseness, I'm also using the $.get function which is a shorthand for your $.ajax({method:get... stuff
$.get('https://api.weather.gov/alerts/active?area='+stateWarn.join(','),function(r){
  console.log(r)
});

Обратите внимание на кусок stateWarn.join? Это означает, что по сути то, что мы отправляем в качестве нашего запроса, https://api.weather.gov/alerts/active?area=MA,NH,NY,RI. Что ... работает! Обратите внимание, конечно, что это, вероятно, не вернет никаких реальных данных,поскольку в любой из этих областей в настоящее время не происходит никаких ужасных погодных явлений.


Множественные асинхронные запросы Проблема с асинхронностью - это довольно неудобно - отправить запрос A, затем B,затем C "для произвольного числа запросов. Поэтому, поскольку формат https://api.weather.gov/alerts/active/area/STATE принимает только ОДИН аргумент, вам, по сути, нужно, чтобы запрос каждого состояния вызывал следующий в строке:

const stateWarn = ["MA", "NH", "NY", "RI"];
let i = 0,
  responses = [];

function getNext() {
  $.get('https://api.weather.gov/alerts/active/area/' + stateWarn[i], function(r) {
    responses.push(r);
    if (i < stateWarn.length) {
      i++
      getNext()
    }
  })
}

Но ... это действительно неловко и будет неприятно, если у вас А) будет больше, чем несколько пунктов, или Б), если вы пройдете через этоСписок занимает дольше , чем ваша первоначальная функция обновления оповещения.Вместо этого мы хотели бы сделать что-то вроде этого.

const alertProms = [],
  stateWarn = ["MA", "NH", "NY", "RI"];
stateWarn.forEach(function(st) {
  proms.push($.get('https://api.weather.gov/alerts/active/area/' + st))
})
Promise.all(alertProms).then(function(r) {
  console.log(r)//this would be ALL your requests.
})

Используется то, что называется Обещания .Хотя я не буду вдаваться в огромные подробности о них здесь, у Обещаний в основном есть три состояния: Ожидание, Успех и Отказ.Есть также множество связанных функций с Обещаниями, такими как Promise.all(array).Эта конкретная функция принимает массив объектов, подобных HTTP-запросам (например, тот, который я сделал выше в areaProms), и, когда каждый запрос возвращается, своего рода сравнивает общее количество отправленных запросов с количеством исходных запросов, которые мысделал.

Это немного более сложное знание, но абсолютно необходимое знание, как только вы попадаете в более сложные HTTP / AJAX вещи.

Если вы хотите узнать больше, я действительно рекомендую вам прочитать MDNстраница на нем здесь , и, в частности, раздел о композиции.

0 голосов
/ 23 октября 2018

Я думаю, что это должно достичь того, чего вы пытаетесь достичь.Вы можете сделать так, чтобы при каждом запуске оно выталкивало самое последнее состояние из стека:

var stateWarn = ["MA", "NH", "NY", "RI"],
    dataTimeCheck,
    intervalId;

$(window).on('load', CheckWarnings);

function setupInterval() {
    if (intervalId) {
      return;
    }

    intervalId = setInterval(CheckWarnings, REFRESH_FREQ);
}

function onSuccess(data) {
  if (data === null) {
     console.log("Data returning with NULL!");
     LoadError();
     return;
  }

  dataTime = data.updated;

  if (!dataTimeCheck) {
     console.log("No check available...creating dataTimeCheck variable and running jsonCrawler.");
     dataTimeCheck = dataTime;
     console.log("Setting initial datatimeCheck variable to: " + dataTimeCheck);
     jsonCrawler(data);
  } else if (!(dataTime == dataTimeCheck)) {
     console.log("'data' and 'dataTimeCheck' variables do not match... running jsonCrawler.")
     dataTimeCheck = dataTime;
     jsonCrawler(data);
  } else if (dataTime == dataTimeCheck) {
     console.log("No new data detected.")
  }
}

function CheckWarnings() {
  var curState = stateWarn.pop();

  if (!curState) {
      if (intervalId) {
         window.clearInverval(intervalId);
      }
      return;
  }

  arrayEvents = [];
  console.log("Checking API...");

  $.ajax({
      url: 'https://api.weather.gov/alerts/active/area/' + curState,
      jsonp: false,
      type: 'get',
      jsonpCallback: 'callback',
      cache: true,
      mode: 'no-cors',
      dataType: 'json',
      crossDomain: true,
      success: function(data) {
         onSuccess(data);

         if (!invervalId) {
            setupInterval();
         }
      }
  });
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...