3

Здравствуйте уважаемые форумчане, подскажите пожалуйста. Есть около 10 всяких различных методов которые используют Аякс, и они продолжают расти. Для каждого метода я пишу:

    $.ajax({
        type: "POST",
        url: url,
        data: params,
        cache: false,
        dataType: "json",
        success: function(data) {
            ......
        }, error: function(request, error, status) {
            .......
        }
    }); 

Сделал функцию getAjax(url, params) в которую передаю данные для отправки. Сам вопрос: как мне из аякс вернуть object data для дальнейшей работы с ним извне? Что бы не писать сам запрос аякс по 20 раз. Имеется ввиду дальнейшая работа с: data.success, data.id, data.name и т.д. вне самого аякс-запроса.

4 Answers4

3

Можно передать обработчик ответа в функцию:

// этот url для примера, он возвращает маленький json, 
// его запросим несколько раз, но это могли бы быть и разные url 
let url = 'https://www.jsonstore.io/64f72be3625c31003a460573a347aa4823ef8b1a62d0e768921972fe6880809d';

getSettings(function(settings) { // вот тут получены все настройки console.log(settings) });

function getSettings(callback) {

// объект, в который сохраняются результаты нескольких запросов let settings = {};

// тут могли бы быть и разные Url getAjax(url, save('key1')); getAjax(url, save('key2')); getAjax(url, save('key3')); getAjax(url, save('key4')); getAjax(url, save('key5'));

function save(key) {

// функция, которая будет вызвана, когда отработает getAjax
return function(data) {

  // сохраняем полученные данные в объект settings 
  settings[key] = data;

  // колбек будет вызван только когда в объекте settings образуется 5 ключей
  if(Object.keys(settings).length === 5)
    callback(settings)
}

} }

function getAjax(url, func){ $.ajax({ type: "GET", url: url, cache: false, success: func, error: function(request, error, status) { console.log(error) } }); }

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

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


Так же рекомендую присмотреться к fetсh, это хоть и новое api но работает уже почти везде

let url = 'https://www.jsonstore.io/64f72be3625c31003a460573a347aa4823ef8b1a62d0e768921972fe6880809d';

fetch(url).then(r => r.json()).then(d => console.log(d))

  • Но как связать функцию getAjax с моими методами? Или спрошу даже так: Как управлять функцией getAjax внутри моих методов в которых я пишу основную логику в зависимости от полученного результата? – sergei1094 Jun 12 '19 at 09:55
  • У меня есть метод, например getSettings(){....} внутри него я хочу выполнить getAjax() {...} и в зависимости о того что придёт от getAjax я хочу обработать данные в getSettings(){....} – sergei1094 Jun 12 '19 at 10:04
  • Ну если у меня грубо сказать десять таких getSettings(){....},getSettings2(){....}....как то объёмно получается писать для каждого метода аякс запрос – sergei1094 Jun 12 '19 at 10:30
  • как мне получить доступ теперь к данным success? – sergei1094 Jun 12 '19 at 10:34
2

Используйте fetch или промисифицируйте $.ajax:

function ajax(url, params, options = {}) {
  return new Promise((resolve, reject) => {
    $.ajax(Object.assign({
      type: "GET",
      url,
      data: params,
    }, options))
      .done(resolve)
      .fail(reject);
  });
}

let url = 'https://httpbin.org/get'; // Можно использовать все преимущества промисов: Promise.all([ ajax(url, {id: 1}), ajax(url, {id: 2}), ajax(url, {id: 3}), ajax(url, {id: 4}, {cache: false}), // можно добавлять доп. параметры ]).then(results => console.log(results)) // выводим все результаты

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
vp_arth
  • 27,179
1

На JS я делал так:

function ajaxGET(url, callback) {
  var request = new XMLHttpRequest();

  request.onreadystatechange = function() {
    if (request.readyState == 4) {
      var status = request.status;
      if (status == 200) {
        callback(request.responseText);
      }
    }
  };

  request.open("GET", url);
  request.setRequestHeader("X-Requested-With", "XMLHttpRequest");
  request.send();
}

callback - функция для возврата.

Пример вызова:

  ajaxGET(get_img_url, function(data) {
    changeSlide(data, id);
  });
1

Давайте перейдем в документацию, выберем один из примеров, и постепенно изменяя и наращивая функционал, добьёмся желаемого поведения.

// Отправляем данные на сервер.
var request = $.ajax({
  // ... код.
});

// Уведомляем пользователя, как только запрос будет завершен.
// Альтернатива создания обработчика `success`.
request.done(function(response) {
  // ... код.
});

// Если запрос не удался, предупреждаем пользователя.
// Альтернатива создания обработчика `error`.
request.fail(function(jqXHR, textStatus) {
  // ... код.
});

При этом обратите внимание, что запрос будет выполнен единожды, не зависимо от того сколько раз впоследствии будет выполнен метод request.done(...), например:

var request = $.ajax('https://jsonplaceholder.typicode.com/posts/88');

request.fail(function(jqXHR, status) { alert('Request failed: ' + textStatus); });

request.done(function(response, status, jqXHR) { $('#header').text(response.title); });

request.done(function(response, status, jqXHR) { $('#body').text(response.body); });

<h3 id="header"></h3>
<p id="body"></p>

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

На данном этапе возникает проблема 1: постоянное формирование тела $.ajax метода. Создадим подобие вашей функции getAjax(url, params).

function get(resource, params = {}) {
  return $.ajax({
    type: 'GET',
    url: resource,
    data: params,
    cache: false,
    headers: {
      'Content-type': 'application/json; charset=UTF-8'
    },
    statusCode: {
      404: function() {
        alert('Рage not found.');
      }
    }
  });
}

var request = get('https://jsonplaceholder.typicode.com/posts/88');

request.fail(function(jqXHR, status) { alert('Request failed: ' + status); });

request.done(function(response, status, jqXHR) { $('#header').text(response.title); $('#body').text(response.body); });

<h3 id="header"></h3>
<p id="body"></p>

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

Проблема 2: постоянные обертки done...done...fail от промиса. Добавим "сахару" в виде async/await, плюс обработку ошибок через try...catch.

function get(resource, params = {}) {
  return $.ajax({
    type: 'GET',
    url: resource,
    data: params,
    cache: false,
    headers: {
      'Content-type': 'application/json; charset=UTF-8'
    },
    statusCode: {
      404: function() {
        alert('Page not found.');
      }
    }
  });
}

function renderList(articles) { $.each(articles, function(index, article) { $("#results").append(&lt;li&gt;${article.title}&lt;/li&gt;); }); }

// Пометили функцию как асинхронную async, // заменили .done на заявление await. async function loadList() { try { // Дожидаемся ответа response для дальнейшей работы. const articles = await get('https://jsonplaceholder.typicode.com/posts'); console.log('Записи загружены.');

// К этому моменту `ajax` запрос
// уже выполнен, ответ уже получен. 
renderList(articles);
console.log('Записи отрисованы.');

} catch (error) { // Все ошибки будут перехватываться здесь. console.error('error'); } }

$(document).ready(function() { loadList(); });

<ul id="results"></ul>

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>