Пишу про разработку вообще и в частности про: JavaScript, HTML5, CSS3, AngularJS, ReactJS, Agile.

ES6 Promises – последовательный вызов

Ну вот и пришла пора поговорить о ES6 Promises, как они описаны в спецификации ES6 (ES2015). Поговорим об этом в контексте определенной задачи. Просто так обсуждать этот функционал кажется скучным, по-этому сразу будем решать проблемы.

Проблема достаточно простая, но вместе с тем, если подумать над ее решением, то можно прийти к достаточно интересным ответам. А вот уже само исследование нам поможет стать более опытными программистами.

js-promises

У нас есть некий список элементов, например вот такой:

Да, да – ничего интересного, все тривиально и скучно. Но это не помешает нам идти дальше 😉 Так вот, предположим, что это список описывает некую последовательность вызовов, которую нам нужно совершить. Например, все это URL адреса и нужно последовательно к ним обратиться. Почему последовательно? Ну, например, нам приходится как-то использовать ответ предыдущего запроса для того чтобы сформировать следующий.

Для запроса используется некая функция, которую мы имплементируем очень просто:

Что тут происходит:

Вполне себе реальная ситуация для сетевого запроса.

reduce()

Теперь нам нужно обеспечить последовательный вызов этих запросов. Для этого воспользуемся стандартным методом массива reduce(). Посмотрим на небольшой пример:

Итак, при каждой итерации reduce вызывает переданный ему callback и передает в него предыдущее значение (полученное, из того что вернул предыдущий вызов callback’а) и нынешнее значение элемента массива. Мы можем это использовать для того чтобы сцепить в цепочку все наши Promise.

А использовать мы будем тот факт, что когда мы вызываем promise.then(), то на выходе получаем новый Promise.

Полностью работающий пример:

JS Bin on jsbin.com

forEach()

Можно переписать это решение просто с циклом, например с forEach()

Вполне возможно, что это решение будет выглядеть понятнее, но требуется использовать дополнительную переменную. Полный код:

JS Bin on jsbin.com

Рекурсия

Разумеется, можно все это решить и рекурсивной функцией, которая будет себя вызывать, пока не пройдется по всем элементам массива:

JS Bin on jsbin.com

Ссылки по теме:
Mozilla: Array.prototype.reduce()
Mozilla: Promise

Поделиться:
comments powered by Disqus