2015-02-09 6 views
1

У меня есть функция, которая выдает два асинхронных запроса перед получением некоторых данных.Отклонение внутреннего обещания после первоначального обещания преуспело?

Вызывающий метод не обязательно должен знать о его деталях реализации. Все потребности абонентов:

  • Данные возвращаются со второго запроса.
  • Возможность вызывать прерывание и не возвращать данные.

Это осложняется тем фактом, что прерывание может быть вызвано после того, как будет сделано первое обещание. Второй запрос уже находится в полете, но вызывающий абонент еще не получил данные. Таким образом, вызывающий абонент предполагает, что он может вызывать прерывание, но отказ от первого обещания не будет иметь никакого эффекта.

Я работаю над этим вопросом со следующим, но он чувствует себя довольно взломанным. Я что-то упускаю?

var ajaxOptions = { 
 
    url: 'https://www.googleapis.com/youtube/v3/search', 
 
    data: { 
 
    part: 'id', 
 
    key: 'AIzaSyDBCJuq0aey3bL3K6C0l4mKzT_y8zy9Msw', 
 
    q: 'Hello' 
 
    } 
 
}; 
 

 
function search(options) { 
 
    var jqXHR = $.ajax(ajaxOptions); 
 

 
    var innerJqXHR = null; 
 
    jqXHR.then(function(data, statusText, jqXHR) { 
 
    innerJqXHR = $.ajax(ajaxOptions); 
 
    innerJqXHR.done(options.done); 
 
    innerJqXHR.fail(options.fail); 
 

 
    return innerJqXHR; 
 
    }, options.fail); 
 

 
    return { 
 
    promise: jqXHR, 
 
    innerPromise: innerJqXHR, 
 
    fullAbort: function() { 
 
     jqXHR.abort(); 
 

 
     if (innerJqXHR !== null) { 
 
     innerJqXHR.abort(); 
 
     } 
 
    } 
 
    } 
 
} 
 

 
var searchReturn = search({ 
 
    done: function() { 
 
    console.log('inner done'); 
 
    }, 
 
    fail: function() { 
 
    console.log('inner or outer fail'); 
 
    } 
 
}); 
 

 
searchReturn.fullAbort();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

+0

Непонятно, как это должно работать. Что это значит: возможность вызывать прерывание и не возвращать данные. – MaxZoom

+0

Я собирался предложить вам более простой способ сделать это, но код для меня не имеет смысла. Вы выполняете '$ .ajax (ajaxOptions)' дважды один за другим. Я бы подумал, что ваш второй вызов ajax будет отличаться от первого и будет включать данные, возвращенные с первого, но ваш код не показывает этого. – jfriend00

+0

Я просто использовал вызов AJAX в качестве примера, поскольку это не укладывалось в мою проблему. На практике каждый вызов AJAX отличается и преобразует данные. –

ответ

1

Поскольку ваш код выглядит немного как псевдо-код (без ответа вопросы в нем для меня), то лучшее, что я могу предложить рамки идеи. Общая идея состоит в том, что вы возвращаете две вещи из своей функции поиска, обещание, которое разрешается только тогда, когда разрешены оба вызова ajax и функция прерывания, которую можно вызвать для прервать процесс.

function search(options) { 
    var activeAjax = $.ajax(args for first ajax call).then(function(data) { 
     // second ajax call changes activeAjax so abort will work 
     // on the active ajax call 
     activeAjax = $.ajax(args for second ajax call).then(function(data) { 
      activeAjax = null; 
      // collect your final data here and return it 
      // this will be the resolved value of the final promise 
      return finalData; 
     }); 
     return activeAjax; 
    }); 

    return { 
     promise: activeAjax, 
     abort: function() { 
      if (activeAjax) { 
       activeAjax.abort(); 
      } 
     } 
    }; 
} 

// usage: 
var searchInProgress = search(...); 
searchInProgress.promise.then(function(data) { 
    // search finished successfully, answer is in data 
}, function(err) { 
    // either one of the promises failed 
}); 

// and, at any time, you can call searchInProgress.abort(); 
+0

Yeppers. Это похоже на единственное решение. Другая мысль, что у меня была, была отменой функции прерывания обещания обещания и переопределения ее тем, что прерывает то, что имеет активный аякс, но я думаю, что это будет более запутанным. Я просто надеялся, что есть способ прервать, какова бы ни была часть цепочек обещаний, но я не думаю, что есть! :) –

+0

@SeanAnderson - прерывание не является стандартной функцией обещаний jQuery и обещаний по цепочке/вложенности, как мы делаем здесь, создает больше обещаний, которые не обязательно будут иметь настраиваемые методы, поэтому я думал, что было бы безопаснее НЕ пытаться добавить метод прерывания непосредственно к обещанию, таким образом возвращая наш собственный объект, который имеет метод abort() 'на нем, который, как мы знаем, безопасен. – jfriend00

+0

Конечно, я согласен с этим решением. Я просто (немного?) Удивлен, что обещания поддерживают выполнение цепочки с помощью .then(), но не поддерживают отцепление цепочки. –

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