Плагин Jquery-jsonp и отложенные объекты, не откладывается

#jquery #error-handling #jsonp #jquery-deferred

#jquery #обработка ошибок #jsonp #jquery-отложенный

Вопрос:

Я пытаюсь использовать плагин jQuery-jsonp с отложенными объектами jQuery, но пока мне не везет.

Цель состоит в том, чтобы вызвать API, получить данные и разработать их. Поскольку я использую один и тот же вызов для извлечения и обработки разных наборов данных для разных целей, я структурировал свой код таким образом, чтобы избежать явного повторения одного и того же вызова API в каждой разрабатывающей функции:

 function callAPI(){
  return $getJSON(url);
}

function doStuff1(){
  $.when(callAPI)
  .then(function(data){
    //get the data and elaborate them for purpose #1
  })
}

function doStuff2(){
  $.when(callAPI)
  .then(function(data){
    //get a different set of data from same API
    // and elaborate them for purpose #2
  })
}
  

Проблема в том, что я попробовал тот же подход, заменив $.getJSON() на $.jsonp() из плагина Джулиана Обура (http://code.google.com/p/jquery-jsonp /) но отсрочка не работает.

У меня есть несколько ограничений на это, и я не могу их изменить:

* Вызовы API должны использовать JSONP.

* Я должен иметь возможность обнаруживать ошибки (независимо от того, какого рода), отсюда и использование плагина jQuery-jsonp, единственного решения, которое я нашел до сих пор.

Я изучал отложенный объект jQuery, искал форумы jQuery, Stackoverflow и глубины Интернета и прочитал все на странице плагина. Я попробовал несколько подходов, но пока ни один из них не сработал (как будто отложенного даже не было). Моя гипотеза заключается в том, что отсрочки не работают с плагином jquery-jsonp из-за его структуры (именно это позволяет ему улавливать ошибки), а также потому, что $.jsonp сам по себе не является отложенным, как $.ajax, но я никоим образом не эксперт, поэтому мне нужен совет из этоговеликолепное сообщество.

Одно из решений, которое я нашел, и оно работает для меня, — передать функцию в качестве параметра функции callAPI, чтобы при успешном выполнении она могла выполнить то, что мне нужно, не повторяясь.

Итак, моя функция callAPI будет изменена следующим образом:

 function callAPI(func){
 $.jsonp({
   "url": url,
   "success": function(data) {
     func();
   },
   "error": function(d,msg) {
    //show error message
   }
 })
}

callAPI(doStuff1);
//or
callAPI(doStuff2);
  

Но, поскольку необходимость управления ошибками возникла на поздней стадии разработки, и я, будучи новичком, не думал об этом раньше, это означало бы переписывание целой кучи кода. Так что, если кому-то удалось использовать отсрочки с плагином jquery-jsonp, это было бы здорово знать.

Спасибо вам всем.

Флавия

Ответ №1:

Я думаю, это то, что вы хотите. Вы должны сопоставить внутренний API jQuery-jsonp с вызовом методов отложенного объекта.

 function callAPI(url){
  return $.Deferred(function(dfd) {
    $.jsonp({
      url: url
      ,success: dfd.resolve
      ,error: dfd.reject
      ,complete: dfd.always
    });
  }).promise();
}
  

Тогда вы должны иметь возможность использовать

 $.when(callAPI('url #1'), callAPI('url #2'))
  .done(function(response1, response2) {
    // each response will be [ json , STR_SUCCESS ] based on Jquery-jsonp's API
    var json1 = response1[0];
    ...
  })
  .error(function(error1, error2) {
    // each response will be [ xOptions , type ] based on Jquery-jsonp's API
    ...
  })
;
  

Комментарии:

1. Спасибо! (и извините за очень задержанный принятый ответ.) В конце концов, мы также являемся поставщиками api, и мои коллеги из серверной части решили, что API должен возвращать 200, даже если произошла ошибка, с ответом, детализирующим ошибку. Подавляющее большинство ошибок было связано с пустыми элементами или отсутствующими аргументами, поэтому у нас также был способ определить, что именно привело к взрыву API, и в то время это имело смысл. Но в итоге ошибки, ведущие прямо в ад (500, 400 или 404), были обработаны с помощью .error() . (но мы полностью переработали эту вещь, поэтому смогли сделать несколько лучших вариантов :))