Промис не успевает резолвиться в цикле
Если не обращать внимание на другие странности кода, то, очевидно, вы делаете return не там, где хотите. Но такой код всё равно работать не может, вы должны понимать, что Promise возвращает ответ асинхронно и передаёт его в коллбэк .then() , и в вашем случае внутри filter всегда будет true, т.к. возвращённый объект Promise существует. А вот например метод Promise.filter, похоже в вашем случае это то, чем нужно заменить filter underscore.
Отслеживать
36.1k 2 2 золотых знака 56 56 серебряных знаков 83 83 бронзовых знака
ответ дан 20 янв 2016 в 19:27
11111000000 11111000000
3,599 12 12 серебряных знаков 25 25 бронзовых знаков
Промисы: обработка ошибок
Цепочки промисов отлично подходят для перехвата ошибок. Если промис завершается с ошибкой, то управление переходит в ближайший обработчик ошибок. На практике это очень удобно.
Например, в представленном ниже примере для fetch указана неправильная ссылка (сайт не существует), и .catch перехватывает ошибку:
fetch('https://no-such-server.blabla') // ошибка .then(response => response.json()) .catch(err => alert(err)) // TypeError: failed to fetch (текст может отличаться)
Как видно, .catch не обязательно должен быть сразу после ошибки, он может быть далее, после одного или даже нескольких .then
Или, может быть, с сервером всё в порядке, но в ответе мы получим некорректный JSON. Самый лёгкий путь перехватить все ошибки – это добавить .catch в конец цепочки:
fetch('/article/promise-chaining/user.json') .then(response => response.json()) .then(user => fetch(`https://api.github.com/users/$`)) .then(response => response.json()) .then(githubUser => new Promise((resolve, reject) => < let img = document.createElement('img'); img.src = githubUser.avatar_url; img.className = "promise-avatar-example"; document.body.append(img); setTimeout(() =>< img.remove(); resolve(githubUser); >, 3000); >)) .catch(error => alert(error.message));
Если все в порядке, то такой .catch вообще не выполнится. Но если любой из промисов будет отклонён (проблемы с сетью или некорректная json-строка, или что угодно другое), то ошибка будет перехвачена.
Неявный try…catch
Вокруг функции промиса и обработчиков находится «невидимый try..catch «. Если происходит исключение, то оно перехватывается, и промис считается отклонённым с этой ошибкой.
Например, этот код:
new Promise((resolve, reject) => < throw new Error("Ошибка!"); >).catch(alert); // Error: Ошибка!
…Работает так же, как и этот:
new Promise((resolve, reject) => < reject(new Error("Ошибка!")); >).catch(alert); // Error: Ошибка!
«Невидимый try..catch » вокруг промиса автоматически перехватывает ошибку и превращает её в отклонённый промис.
Это работает не только в функции промиса, но и в обработчиках. Если мы бросим ошибку ( throw ) из обработчика ( .then ), то промис будет считаться отклонённым, и управление перейдёт к ближайшему обработчику ошибок.
new Promise((resolve, reject) => < resolve("ок"); >).then((result) => < throw new Error("Ошибка!"); // генерируем ошибку >).catch(alert); // Error: Ошибка!
Это происходит для всех ошибок, не только для тех, которые вызваны оператором throw . Например, программная ошибка:
new Promise((resolve, reject) => < resolve("ок"); >).then((result) => < blabla(); // нет такой функции >).catch(alert); // ReferenceError: blabla is not defined
Финальный .catch перехватывает как промисы, в которых вызван reject , так и случайные ошибки в обработчиках.
Пробрасывание ошибок
Как мы уже заметили, .catch ведёт себя как try..catch . Мы можем иметь столько обработчиков .then , сколько мы хотим, и затем использовать один .catch в конце, чтобы перехватить ошибки из всех обработчиков.
В обычном try..catch мы можем проанализировать ошибку и повторно пробросить дальше, если не можем её обработать. То же самое возможно для промисов.
Если мы пробросим ( throw ) ошибку внутри блока .catch , то управление перейдёт к следующему ближайшему обработчику ошибок. А если мы обработаем ошибку и завершим работу обработчика нормально, то продолжит работу ближайший успешный обработчик .then .
В примере ниже .catch успешно обрабатывает ошибку:
// the execution: catch -> then new Promise((resolve, reject) => < throw new Error("Ошибка!"); >).catch(function(error) < alert("Ошибка обработана, продолжить работу"); >).then(() => alert("Управление перейдёт в следующий then"));
Здесь блок .catch завершается нормально. Поэтому вызывается следующий успешный обработчик .then .
В примере ниже мы видим другую ситуацию с блоком .catch . Обработчик (*) перехватывает ошибку и не может обработать её (например, он знает как обработать только URIError ), поэтому ошибка пробрасывается далее:
// the execution: catch -> catch -> then new Promise((resolve, reject) => < throw new Error("Ошибка!"); >).catch(function(error) < // (*) if (error instanceof URIError) < // обрабатываем ошибку >else < alert("Не могу обработать ошибку"); throw error; // пробрасывает эту или другую ошибку в следующий catch >>).then(function() < /* не выполнится */ >).catch(error => < // (**) alert(`Неизвестная ошибка: $`); // ничего не возвращаем => выполнение продолжается в нормальном режиме >);
Управление переходит от первого блока .catch (*) к следующему (**) , вниз по цепочке.
Необработанные ошибки
Что произойдёт, если ошибка не будет обработана? Например, мы просто забыли добавить .catch в конец цепочки, как здесь:
new Promise(function() < noSuchFunction(); // Ошибка (нет такой функции) >) .then(() => < // обработчики .then, один или более >); // без .catch в самом конце!
В случае ошибки выполнение должно перейти к ближайшему обработчику ошибок. Но в примере выше нет никакого обработчика. Поэтому ошибка как бы «застревает», её некому обработать.
На практике, как и при обычных необработанных ошибках в коде, это означает, что что-то пошло сильно не так.
Что происходит, когда обычная ошибка не перехвачена try..catch ? Скрипт умирает с сообщением в консоли. Похожее происходит и в случае необработанной ошибки промиса.
JavaScript-движок отслеживает такие ситуации и генерирует в этом случае глобальную ошибку. Вы можете увидеть её в консоли, если запустите пример выше.
В браузере мы можем поймать такие ошибки, используя событие unhandledrejection :
window.addEventListener('unhandledrejection', function(event) < // объект события имеет два специальных свойства: alert(event.promise); // [object Promise] - промис, который сгенерировал ошибку alert(event.reason); // Error: Ошибка! - объект ошибки, которая не была обработана >); new Promise(function() < throw new Error("Ошибка!"); >); // нет обработчика ошибок
Это событие является частью стандарта HTML.
Если происходит ошибка, и отсутствует её обработчик, то генерируется событие unhandledrejection , и соответствующий объект event содержит информацию об ошибке.
Обычно такие ошибки неустранимы, поэтому лучше всего – информировать пользователя о проблеме и, возможно, отправить информацию об ошибке на сервер.
В не-браузерных средах, таких как Node.js, есть другие способы отслеживания необработанных ошибок.
Итого
- .catch перехватывает все виды ошибок в промисах: будь то вызов reject() или ошибка, брошенная в обработчике при помощи throw .
- .then также перехватывает ошибки таким же образом, если задан второй аргумент (который является обработчиком ошибок).
- Необходимо размещать .catch там, где мы хотим обработать ошибки и знаем, как это сделать. Обработчик может проанализировать ошибку (могут быть полезны пользовательские классы ошибок) и пробросить её, если ничего не знает о ней (возможно, это программная ошибка).
- Можно и совсем не использовать .catch , если нет нормального способа восстановиться после ошибки.
- В любом случае нам следует использовать обработчик события unhandledrejection (для браузеров и аналог для других окружений), чтобы отслеживать необработанные ошибки и информировать о них пользователя (и, возможно, наш сервер), благодаря чему наше приложение никогда не будет «просто умирать».
Как настроить VS Code для разработки на JavaScript
Visual Studio Code – популярный бесплатный редактор кода, созданный Microsoft’ом для программистов. VS Code никак не связан с Visual Studio. VS Code работает быстрее Атома, активно развивается и легко расширяется плагинами.
- отладчик кода
- встроенный терминал
- удобные инструменты для работы с Git
- подсветка синтаксиса для множества популярных языков и файловых форматов
- удобная навигация
- встроенный предпросмотр Markdown
- умное автодополнение
- встроенный пакетный менеджер
Пакетный менеджер нужен для установки и удаления пакетов расширений (плагинов). Для удобной разработки на JavaScript для бэкенда и фронтенда нужно установить несколько пакетов.

Для установки нового пакета зайдите в выпадающее меню «View» на вкладку «Extensions» и введите название пакета в строке поиска, а затем нажмите кнопку «Install».
Babel и ES6
VS Code содержит понятие «сборки проекта». Редактор можно настроить таким образом, чтобы сборка JavaScript-проекта заключалась в конвертации кода из ES6 в читаемый ES5 с Source Maps с помощью Babel.
Добавьте таск (задание) в файл tasks.json в директории .vscode в корне вашего проекта:
"version": "2.0.0", "type": "shell", "tasks": [ "label": "watch", "command": "$/node_modules/.bin/babel src --out-dir dist -w --source-maps", "group": "build", "isBackground": true > ] >
Теперь комбинация клавиш Shift+Ctrl+B (Windows/Linux) или Shift+CMD+B (macOS) запустит сборку.
Стандарты кодирования
Eslint – это утилита, проверяющая стандарты кодирования на JavaScript. Стандарт де-факто в мире JS.

Нужно сначала установить eslint в системе, а потом установить расширение VS Code, которое будет использовать установленный линтер. Есть разные способы интеграции линтера с расширением. Мы рассмотрим установку линтера глобально в системе.
- Установите Node.js, используя пакетный менеджер вашей операционной системы.
- Установите eslint командой npm install -g eslint . Вероятно, вам понадобится использовать sudo .
- Установите плагины, которые конфигурируют eslint . Без них (по умолчанию) eslint ничего не проверяет.
npm install -g eslint-config-airbnb-base eslint-plugin-import
extends: - 'airbnb-base' env: node: true browser: true
Автоматическое дополнение
VS Code содержит мощную систему анализа кода для автодополнений и подсказок – IntelliSense.
IntelliSense работает сразу, но для настройки деталей нужно создать конфигурационный файл jsconfig.json .
jsconfig.json
Если положить в корень директории с JavaScript-проектом конфигурационный файл jsconfig.json , то VS Code будет использовать эту конфигурацию для работы с вашим проектом. Вот пример такого файла:
"compilerOptions": "target": "ES6" >, "exclude": [ "node_modules", "**/node_modules/*" ] >
Здесь можно настроить, например, какие директории стоит исключить из системы автодополнений IntelliSense. VS Code совместим с node, webpack, bower, ember и другими популярными инструментами. Полная документация по jsconfig доступна на сайте VS Code.
Отладка
VS Code содержит встроенный отладчик кода. Вы можете, например, отметить брейкпойнты (точки остановки) и следить за состоянием приложения в реальном времени.
Для отладки бэкенд-кода достаточно встроенных возможностей. Для отладки фронтенд-кода нужно установить плагин для соответствующего браузера:
- Debugger for Chrome
- Debugger for Firefox
- Debugger for Edge
Подробнее об отладке можно узнать на сайте VS Code.
Ссылки
Курс по настройке окружения для работы в современной экосистеме JavaScript.
10 расширений для VS Code, без которых я не могу программировать
VS Code — мой любимый редактор кода. Это — самый популярный из существующих редакторов, возможности которого можно расширять практически до бесконечности. И, что удивительно, разработала его компания Microsoft. Я полагаю, что ни один из других редакторов и ни одна из других IDE не может дать разработчику хотя бы половину того, что способен дать ему VS Code. Одна из сильных сторон VS Code — это система расширений. Она позволяет создавать расширения буквально на все случаи жизни. Хочу рассказать вам о моём топ-10 расширений для VS Code.
1. Beautify

Для установки расширения воспользуйтесь в VS Code клавиатурным сокращением CTRL+P , введите в открывшееся поле нижеприведённую команду и нажмите Enter .
ext install HookyQR.beautify
Расширение Beautify позволяет форматировать html-, js-, css-, JSON- и sass-код. Параметрами форматирования можно управлять. Это расширение является надстройкой над стандартной системой js-beautify и позволяет разработчику форматировать код именно так, как ему нужно.
2. Better Comments

ext install aaron-bond.better-comments
Расширение Better Comments позволяет расширить возможности по работе с комментариями. В частности, оно позволяет делить комментарии на категории. Это могут быть уведомления, запросы, списки дел, примечания.

Использование Better Comments
3. Bookmarks

ext install alefragnani.Bookmarks
Расширение Bookmarks — это настоящий спасательный круг для программистов. Особенно для тех, которые потерялись среди тысяч строк кода. Это расширение позволяет прикреплять к строкам кода закладки. Если у строки кода есть закладка — к этой строке можно легко перейти, воспользовавшись списком закладок.

Закладки в коде
4. Bracket Pair Colorizer 2

ext install CoenraadS.bracket-pair-colorizer-2
Расширение Bracket Pair Colorizer 2 позволяет раскрашивать скобки, что облегчает нахождение пар открывающих и закрывающих скобок. Это очень полезно в тех случаях, когда приходится работать с вложенными друг в друга программными конструкциями.

Пары скобок выделены цветами
5. Format in Context Menus

ext install lacroixdavid1.vscode-format-context-menu
Расширение Format in Context Menus позволяет форматировать файлы, выделяя их в боковой панели и вызывая команду контекстного меню. Это особенно удобно в тех случаях, когда имеется множество файлов, которые нужно отформатировать, но при этом в имеющемся окружении нет поддержки средств для форматирования и линтинга кода.
Работа с Format in Context Menus
6. Git Graph

ext install mhutchie.git-graph
Расширение Git Graph позволяет просматривать структуру репозитория и, пользуясь этой структурой, выполнять различные операции. Это расширение поддаётся тонкой настройкой и обладает множеством возможностей. Вероятно, для того, чтобы как следует его описать, понадобится целая отдельная статья.
Работа с Git Graph
7. GitLens

ext install eamodio.gitlens
Расширение GitLens помогает выяснять авторство кода с использованием аннотаций git blame и линз. Это расширение, кроме прочего, позволяет очень удобно просматривать содержимое репозиториев и узнавать полезные сведения о коде.

Работа с GitLens
8. Indent Rainbow

ext install oderwat.indent-rainbow
Расширение Indent Rainbow позволяет раскрашивать отступы, выделяя разными цветами отступы разных уровней. Это особенно полезно при работе с глубоко вложенными конструкциями в языках наподобие Python.
9. Path Intellisense

ext install christian-kohler.path-intellisense
Расширение Path Intellisense оснащает редактор возможностями по автозавершению путей к файлам. Хотя VS Code поддерживает автозавершение путей и без расширений, эта возможность ограничена только HTML-, CSS- и JavaScript-файлами. Благодаря данному расширению автозавершением путей можно пользоваться при работе с любыми файлами и любыми языками.
Работа с Path Intellisense
10. Total Lines

ext install praveencrony.total-lines
Расширение Total Lines — это маленький удобный инструмент, который выводит в статус-баре сведения о количестве строк в открытом файле. Это — приятное дополнение к моей коллекции расширений.
А какими расширениями для VS Code пользуетесь вы?
Напоминаем, что у нас продолжается конкурс прогнозов, в котором можно выиграть новенький iPhone. Еще есть время ворваться в него, и сделать максимально точный прогноз по злободневным величинам.

- Блог компании RUVDS.com
- Программирование
- Visual Studio
- Софт
- Лайфхаки для гиков