Получить json после ajax с преминением promise

231
28 декабря 2017, 23:37

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

Появилась необходимость использовать эти данные все функции, воспользовался promise

var productinfo = function(id) {
                  var promise = $.ajax({
                    dataType: "JSON",  
                    type: 'POST',
                    url: "serverscript/jsonproduct.php",
                    data: "id="+id,
                  })
                  return promise.done(function(data) {
                    return data
                  })
            }

затем вызываю ее

console.log(productinfo(id))

Получаю такой массив

abort:
always
complete
done
error
fail
getAllResponseHeaders
getResponseHeader
overrideMimeType
pipe
progress
promise
readyState
responseJSON
....    

По сути то,что мне необходимо в дальнейшем использовать тут responseJSON Пробовал достать так

return promise.done(function(data) {
        return data.responseJSON;
    })

Но видимо где-то ошибся,так как возвращает тоже самое.А не нужное мне.

Answer 1

Не возвращает .done то, что Вы возвращаете из функции, которую туда подаете в качестве параметра. Возвращать что-то из этой функции бессмысленно. .done возвращается сразу (и возвращает тот же самый promise) - он всего лишь запоминает функцию, которую Вы туда подали, чтобы вызвать ее, когда "обещание" (promise) исполнится.

Не могут у Вас в коде появится данные, получаемые асинхронно, до того, как придет ответ на запрос.

var productinfo = function(id, callback) {
  $.ajax({
    dataType: "JSON",  
    type: 'POST',
    url: "serverscript/jsonproduct.php",
    data: "id="+id,
    success: callback
  });
}
productinfo(id, function(data) { console.log(data); });
Answer 2

Очень прошу, в 2018 (почти) году не писать код с коллбеками, тем более на фронтенде.. (как предложено в другом ответе). Если Вы хотите использовать jQuery, хотя для этой задачи (опять же в почти-2018-м году), то можете обернуть его в промис вот так.

Сразу отмечу, что данная проблема и лишний код появляется потому, что используется jQuery для запросов, хотя есть fetch и полифилы к нему

Вариант 1:

const getProductInfo = id => new Promise((resolve, reject) => {
  const params = {
      dataType: "JSON",
      type: 'POST',
      url: "serverscript/jsonproduct.php",
      data: "id="+id,
  };
  $.ajax(params)
    .done(data => resolve(data.responseJSON))
    .fail(() => reject('Failed'));
});
// later on..
try {
  const productInfo = await getProductInfo('123');
}
catch (e) {
  // react to error
}

Вариант 2 (удобнее):

const getProductInfo = id => new Promise((resolve, reject) => {
  const params = {
      dataType: "JSON",
      type: 'POST',
      url: "serverscript/jsonproduct.php",
      data: "id="+id,
  };
  $.ajax(params)
    .done(data => resolve(data.responseJSON))
    .fail(() => resolve(null));
});
const productInfo = await getProductInfo('123');
if (!productInfo) {
  console.log('error');
}

Если нет возможности использовать async/await:

getProductInfo('123')
  .then(console.log)
  .catch(console.log);

Вариант с fetch

const getProductInfo = id => fetch('/url.json', {
  method: 'POST'
})
  .then(data => data.json())
  .catch(e => null);
const productInfo = await getProductInfo('123');
if (!productInfo) {
  // log error
}
READ ALSO
Ошибки jQuery — формируются запросы на версию самой jQuery. Как исправить?

Ошибки jQuery — формируются запросы на версию самой jQuery. Как исправить?

Всем привет!) Стоит задача - оптимизировать сайт под Google Page Speed Insights(PSI)Сайт на Wordpres

214
Не срабатывает функция с bind()

Не срабатывает функция с bind()

Почему в данном примере функция handleClick не запускается? При этом, если убрать bind и оставить только handleClick(), то все работает, но теряется контекст

226
Как правильно написать 2 цикла php foreach?

Как правильно написать 2 цикла php foreach?

Привет, подскажите пожалуйста как правильнее написать цикл на PHP + html разметка, ибо и за моего косяка теперь каждый item в item'e

257
Взять комментированный контент из html

Взять комментированный контент из html

Вопрос таковДопустим на сайте есть какие то куски html которые комментированы

383