Максимальное значение для заголовка элемента управления кэшем в HTTP

Исходя из названия вопроса: «Решение обещает одно за другим (то есть в последовательности)?», мы могли бы понять, что ОП больше интересуется последовательной обработкой обещаний по расчету, чем последовательными вызовами per se .

Этот ответ предлагается:

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

Если одновременные вызовы действительно не нужны, см. ответ Бенджамина Грюнбаума, который охватывает последовательные вызовы (и т. д.) всесторонне.

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

Заманчиво думать, что вам нужно использовать Promise.all(arr.map(fn)).then(fn) (как я делал много раз), или саунд-мотив Promise lib (особенно Bluebird's), однако (с учетом этой статьи ) шаблон arr.map(fn).reduce(fn) выполнит это задание с теми преимуществами, которые он имеет:

  • работает с любыми обеими версиями jQuery lib - даже предсовместимыми версиями - используется только .then().
  • дает гибкость для пропуска пропусков или остановки при ошибке, в зависимости от того, что вы хотите с помощью однострочного мод.

Здесь он написан для Q.

var readFiles = function(files) {
    return files.map(readFile) //Make calls in parallel.
    .reduce(function(sequence, filePromise) {
        return sequence.then(function() {
            return filePromise;
        }).then(function(file) {
            //Do stuff with file ... in the correct sequence!
        }, function(error) {
            console.log(error); //optional
            return sequence;//skip-over-error. To stop-on-error, `return error` (jQuery), or `throw  error` (Promises/A+).
        });
    }, Q()).then(function() {
        // all done.
    });
};

Примечание: только тот фрагмент, Q(), специфичен для Q. Для jQuery вам необходимо убедиться, что readFile () возвращает обещание jQuery. С помощью A + libs будут усваиваться иностранные обещания.

Ключевым моментом является обещание сокращения sequence, в котором последовательности обработки readFile обещают, но а не их создание.

И как только вы впитаете это, возможно, слегка раздумывая, когда вы понимаете, что этап .map() на самом деле не нужен! Вся работа, параллельные вызовы плюс последовательная обработка в правильном порядке, может быть достигнута только с помощью reduce() плюс дополнительное преимущество дальнейшей гибкости:

  • конвертировать из параллельных асинхронных вызовов в последовательный асинхронный звонки, просто перемещая одну строку - потенциально полезную во время разработки.

Здесь он снова для Q.

var readFiles = function(files) {
    return files.reduce(function(sequence, f) {
        var filePromise = readFile(f);//Make calls in parallel. To call sequentially, move this line down one.
        return sequence.then(function() {
            return filePromise;
        }).then(function(file) {
            //Do stuff with file ... in the correct sequence!
        }, function(error) {
            console.log(error); //optional
            return sequence;//Skip over any errors. To stop-on-error, `return error` (jQuery), or `throw  error` (Promises/A+).
        });
    }, Q()).then(function() {
        // all done.
    });
};

Это базовый шаблон. Если вы захотите также предоставить данные (например, файлы или некоторые их преобразования) вызывающему, вам понадобится мягкий вариант.

64
задан T Zengerink 27 April 2012 в 10:48
поделиться