Прочитал небольшую статью Тори Волкера "The Pitfalls of Async/Await in Array Loops" про использование
По ходу статьи Тори рассказывает как добиться того, чтобы три промиса были выполнены по порядку с использованием циклов. В начале он показывает неправильно работающий пример с использованием
Статья небольшая, но вполне адекватная. Если у вас в проекте используется
#js #async
https://medium.com/dailyjs/the-pitfalls-of-async-await-in-array-loops-cf9cf713bfeb
async/await
в циклах.По ходу статьи Тори рассказывает как добиться того, чтобы три промиса были выполнены по порядку с использованием циклов. В начале он показывает неправильно работающий пример с использованием
forEach
и объясняет, почему он не работает так как нужно (в комментариях есть больше подробностей). Потом показывает уже работающее решение с использованием map
. В этом примере почти всё работает как ожидается, но промисы не ждут друг друга. В последнем примере используется for...of
, с которым всё ок – каждый промис ждёт выполнения предыдущего.Статья небольшая, но вполне адекватная. Если у вас в проекте используется
async/await
, то статья может быть вам полезна.#js #async
https://medium.com/dailyjs/the-pitfalls-of-async-await-in-array-loops-cf9cf713bfeb
Medium
The Pitfalls of Async/Await in Array Loops
Using async/await while looping through arrays in Javascript loop seems simple, but there’s some non-intuitive behavior to look out for…
Пару дней назад разработчики Chrome твитнули про то, что реализация нового предложения в JS — Promise.allSettled — была добавлена в Chrome 76. Также поддержка нового предложения уже есть в ночных сборках Firefox.
Новая фича — это дополнение к уже существующему
В рамках текущего стандарта можно обработать все промисы подобно
С использованием allSettled этот код становится гораздо проще:
co
#js #proposal #async
https://github.com/tc39/proposal-promise-allSettled
Новая фича — это дополнение к уже существующему
Promise.all()
. Если all()
прекращает работу как только любой из промисов возвращает reject, то allSettled()
дожидается выполнения всех промисов и возвращает массив снапшотов состояния с результатами работы промисов вне зависимости от того были ли среди них промисы с reject.В рамках текущего стандарта можно обработать все промисы подобно
allSettled
, если сделать дополнительную функцию (+обратите внимание на promises.map(reflect)):function reflect(promise) {
return promise.then(
v => ({status: 'fulfilled', value: v }),
error => ({status: 'rejected', reason: error})
);
}
const promises = [fetch('good.html'), fetch('bad.html')];
const results = await Promise.all(promises.map(reflect));
const successfulPromises = results.filter(
p => p.status === 'fulfilled'
);
С использованием allSettled этот код становится гораздо проще:
co
nst promises = [fetch('good.html'), fetch('bad.html')];Promise.allSettled() находится в stage 3. Это значит, что скорее всего он попадёт в стандарт либо в этом, либо в следующем году.
const results = await Promise.allSettled(promises);
const successfulPromises = results.filter(
p => p.status === 'fulfilled'
);
#js #proposal #async
https://github.com/tc39/proposal-promise-allSettled
GitHub
GitHub - tc39/proposal-promise-allSettled: ECMAScript Proposal, specs, and reference implementation for Promise.allSettled
ECMAScript Proposal, specs, and reference implementation for Promise.allSettled - GitHub - tc39/proposal-promise-allSettled: ECMAScript Proposal, specs, and reference implementation for Promise.all...
Как-то я пропустил это небольшое событие. В январе появилось предложение Матиаса Байненса о добавлении в стандарт JavaScript нового метода промисов
Предложение находится на первом этапе рассмотрения в TC39. И я пока не вижу причин, почему его могут выкинуть из стандарта.
UPD: Только что обнаружил, что соавтор предложения Сергей Рубанов — ведущий канала @juliarderity (спецификации и другие горячие новости из мира web).
#js #proposal #async
https://github.com/tc39/proposal-promise-any
any()
.Promise.any()
сигнализирует о том, что один из обрабатываемых промисов был успешно разрешён. Этот метод похож на метод Promise.race()
, но отличается тем, что не завершает работу, если был отклонён один из промисов. Отклонение Promise.any()
происходит только тогда, когда все обрабатываемые промисы были отклонены. Вот небольшой пример, как работает этот метод:const promises = [
fetch('/endpoint-a').then(() => 'a'),
fetch('/endpoint-b').then(() => 'b'),
fetch('/endpoint-c').then(() => 'c'),
];
try {
const first = await Promise.any(promises);
// Один из промисов был успешно разрешён, например 'b'
// При этом и 'a', и 'c' могли быть отклонены
console.log(first);
} catch (error) {
// Все промисы были отклонены
console.log(error);
}
Предложение находится на первом этапе рассмотрения в TC39. И я пока не вижу причин, почему его могут выкинуть из стандарта.
UPD: Только что обнаружил, что соавтор предложения Сергей Рубанов — ведущий канала @juliarderity (спецификации и другие горячие новости из мира web).
#js #proposal #async
https://github.com/tc39/proposal-promise-any
GitHub
GitHub - tc39/proposal-promise-any: ECMAScript proposal: Promise.any
ECMAScript proposal: Promise.any. Contribute to tc39/proposal-promise-any development by creating an account on GitHub.
Сегодня меня занесло в 2015-ый год. Прочитал статью Джека Арчибальда про старые баги браузеров с планированием микрозадач — "Tasks, microtasks, queues and schedules".
Если выполнить такой код:
то в консоль будет выведено: "script start", "script end", "promise", "setTimeout". Такой порядок объясняется тем, что очередь микрозадач (куда попадают выполнение коллбеков MutationObserver и коллбеки промисов) опустошается до выполнения следующей задачи, которая в данном случае создаётся с помощью setTimeout.
В статье описываются ситуации, когда обработка микрозадач обрабатывалась браузерами по-разному. Например, при обработке коллбеков MutationObserver и Promise в рамках одной задачи.
Проверил примеры — браузеры уже пофиксили описанные проблемы. Но всё равно рекомендую почитать статью, если она прошла мимо вас.
#async #history
https://jakearchibald.com/2015/tasks-microtasks-queues-and-schedules/
Если выполнить такой код:
console.log('script start');
setTimeout(() => console.log('setTimeout'), 0);
Promise.resolve().then(() => console.log('promise'));
console.log('script end');
то в консоль будет выведено: "script start", "script end", "promise", "setTimeout". Такой порядок объясняется тем, что очередь микрозадач (куда попадают выполнение коллбеков MutationObserver и коллбеки промисов) опустошается до выполнения следующей задачи, которая в данном случае создаётся с помощью setTimeout.
В статье описываются ситуации, когда обработка микрозадач обрабатывалась браузерами по-разному. Например, при обработке коллбеков MutationObserver и Promise в рамках одной задачи.
Проверил примеры — браузеры уже пофиксили описанные проблемы. Но всё равно рекомендую почитать статью, если она прошла мимо вас.
#async #history
https://jakearchibald.com/2015/tasks-microtasks-queues-and-schedules/
Jakearchibald
Tasks, microtasks, queues and schedules
When I told my colleague Matt Gaunt I was thinking of writing a piece on microtask queueing and execution within the browser's event loop, he said "I'll be honest with you Jake, I'm not going to read that". Well, I've written it anyway, so we're all going…
Пару дней назад в код v8 была добавлена реализация предложения "Top-level await" (Stage 3). Про этот пропозал в канале ещё ничего не было, поэтому хочу написать небольшое объяснение того, какую проблему он решает.
Top-level await добавляет поддержку
Добавление в стандарт top-level await упростит работу с динамическими импортами и модулями, предоставляющими асинхронные ресурсы, например, соединение с базой данных.
#future #async #tc39
https://github.com/tc39/proposal-top-level-await
Top-level await добавляет поддержку
await
на верхнем уровне модуля, то есть вне асинхронных функций, которые декларируются с помощью async
. Это позволяет превратить модуль в некое подобие большой асинхронной функции. При импорте такого модуля асинхронный код, помеченный с помощью ключевого слова await
, будет останавливать выполнение импортирующего модуля до того момента, пока все зависимости не будут зарезолвлены. Вот пример преобразования "асинхронного модуля" с помощью top-level await:// было
import { process } from "./some-module.mjs";
export default (async () => {
const dynamic = await import(computedModuleSpecifier);
const data = await fetch(url);
const output = process(dynamic.default, data);
return { output };
})();
// стало
import { process } from "./some-module.mjs";
const dynamic = import(computedModuleSpecifier);
const data = fetch(url);
export const output = process((await dynamic).default, await data);
Добавление в стандарт top-level await упростит работу с динамическими импортами и модулями, предоставляющими асинхронные ресурсы, например, соединение с базой данных.
#future #async #tc39
https://github.com/tc39/proposal-top-level-await
GitHub
GitHub - tc39/proposal-top-level-await: top-level `await` proposal for ECMAScript (stage 4)
top-level `await` proposal for ECMAScript (stage 4) - tc39/proposal-top-level-await
В блоге Акселя Раушмайера пару дней назад появилась статья про использование асинхронных итераторов со стримами в Node.js — "Easier Node.js streams via async iteration".
Код, который агрегирует поступающие данные из readable stream или, наоборот, записывает данные во writable stream может быть записан компактно, используя возможности асинхронных итераторов (ES2018). Вот пример из статьи. В нём с помощью конструкции
Выглядит очень элегантно. В статье ещё есть хороший пример трансформации стримов с помощью асинхронных генераторов.
В общем, рекомендую почитать, даже если не работаете много с Node.js.
#js #nodejs #async
https://2ality.com/2019/11/nodejs-streams-async-iteration.html
Код, который агрегирует поступающие данные из readable stream или, наоборот, записывает данные во writable stream может быть записан компактно, используя возможности асинхронных итераторов (ES2018). Вот пример из статьи. В нём с помощью конструкции
for await ... of
считывается текст из readable stream и записывается в переменную result:async function readableToString(readable) {
let result = '';
for await (const chunk of readable) {
result += chunk;
}
return result;
}
Выглядит очень элегантно. В статье ещё есть хороший пример трансформации стримов с помощью асинхронных генераторов.
В общем, рекомендую почитать, даже если не работаете много с Node.js.
#js #nodejs #async
https://2ality.com/2019/11/nodejs-streams-async-iteration.html
Александр Сурма рассказал про свой опыт использования WHATWG Streams для реактивного программирования — "Streams for reactive programming ".
WHATWG Streams — низкоуровневый примитив web-плафтормы, который решает проблему эффективной работы с I/O. Он лежит в основе Fetch API. В статье разбирается эксперимент использования стримов для создания observable-like библиотеки
Не думаю, что появление ows заставит кого-то отказаться от Rx.js, но сам по себе эксперимент получился интересный. Рекомендую почитать статью, если хотите узнать побольше про использование WHATWG Streams и особенности реализации observable.
#async #streams #expeimental
https://dassur.ma/things/streams-for-reactive-programming/
WHATWG Streams — низкоуровневый примитив web-плафтормы, который решает проблему эффективной работы с I/O. Он лежит в основе Fetch API. В статье разбирается эксперимент использования стримов для создания observable-like библиотеки
observables-with-streams (ows)
и полноценного приложения на его основе. Эксперимент удался, но вскрыл проблему: в отличие от обычных observable подписчики в ows всегда выполняются асинхронно.Не думаю, что появление ows заставит кого-то отказаться от Rx.js, но сам по себе эксперимент получился интересный. Рекомендую почитать статью, если хотите узнать побольше про использование WHATWG Streams и особенности реализации observable.
#async #streams #expeimental
https://dassur.ma/things/streams-for-reactive-programming/
dassur.ma
Streams for reactive programming — surma.dev
Can you use WHATWG Streams for reactive programming? It seems so. But is it a good idea?
Алан Сторм опубликовал статью про асинхронные генераторы и итераторы — "Async Generators and Async Iteration in Node.js".
Асинхронные итераторы используются вместе с асинхронными генераторами, которые возвращают промисы. Они очень полезны при обработке таких операций, которые возвращают значения порциями с течением времени. Их можно использовать со стримами, при работе с асинхронными API в браузере. На сайте Deno есть пример использования асинхронных итераторов для создания простого web-сервера:
Очень рекомендую почитать статью, если не приходилось работать с асинхронными итераторами ранее. В статье очень хорошо объясняется суть их работы.
#js #async
https://alanstorm.com/async-generators-and-async-iteration-in-node-js/
Асинхронные итераторы используются вместе с асинхронными генераторами, которые возвращают промисы. Они очень полезны при обработке таких операций, которые возвращают значения порциями с течением времени. Их можно использовать со стримами, при работе с асинхронными API в браузере. На сайте Deno есть пример использования асинхронных итераторов для создания простого web-сервера:
import { serve } from "https://deno.land/std@0.50.0/http/server.ts";
for await (const req of serve({ port: 8000 })) {
req.respond({ body: "Hello World\n" });
}
Очень рекомендую почитать статью, если не приходилось работать с асинхронными итераторами ранее. В статье очень хорошо объясняется суть их работы.
#js #async
https://alanstorm.com/async-generators-and-async-iteration-in-node-js/
Alanstorm
Async Generators and Async Iteration in Node.js
This entry is part 4 of 4 in the series Four Steps to Async Iterators. Earlier posts include ES6 Symbols, Javascript Generators, and ES6's Many for Loops and Iterable Objects. This is the most recent post in the series. Four Steps to Async IteratorsES6 S…
Использование AbortController и AbortSignal в Node.js
Джеймс Снелл — контрибьютор Node.js — написал статью про использование AbortController и AbortSignal в Node.js — "Using AbortSignal in Node.js".
Последние два года разработчики Node.js работают над добавлением разных API web-платформы. Результатом этой работы стала реализация AbortController, который появился в стабильной версии Node.js 16.
AbortController и AbortSignal реализуют интерфейс для отмены выполнения асинхронных операций. С его помощью можно прерывать таймеры, асинхронные запросы, отписываться от событий, добавленных с помощью интерфейса EventTarget, который поддерживают некоторые API Node.js. В статье рассказывается о том как использовать AbortController и AbortSignal на примере прерывания асинхронного события по таймауту.
Рекомендую почитать статью всем, так как AbortController доступен не только в Node.js, но и во всех актуальных браузерах.
#nodejs #async #api
https://www.nearform.com/blog/using-abortsignal-in-node-js/
Джеймс Снелл — контрибьютор Node.js — написал статью про использование AbortController и AbortSignal в Node.js — "Using AbortSignal in Node.js".
Последние два года разработчики Node.js работают над добавлением разных API web-платформы. Результатом этой работы стала реализация AbortController, который появился в стабильной версии Node.js 16.
AbortController и AbortSignal реализуют интерфейс для отмены выполнения асинхронных операций. С его помощью можно прерывать таймеры, асинхронные запросы, отписываться от событий, добавленных с помощью интерфейса EventTarget, который поддерживают некоторые API Node.js. В статье рассказывается о том как использовать AbortController и AbortSignal на примере прерывания асинхронного события по таймауту.
Рекомендую почитать статью всем, так как AbortController доступен не только в Node.js, но и во всех актуальных браузерах.
#nodejs #async #api
https://www.nearform.com/blog/using-abortsignal-in-node-js/
Nearform
Using AbortSignal in Node.js | Nearform
Поиск необработанных промисов
Свизек Теллер написал статью про ошибки, приводящие к возникновению необработанных промисов — "Finding unresolved promises in JavaScript".
Необработанные промисы — это большой источник проблем, который может привести к крешу программы. Они возникают при забытом перехвате исключения с помощью
Свизек нашёл научную статью "Finding broken promises in asynchronous JavaScript programs", в которой авторы попробовали автоматизировать поиск подобных ошибок и создали утилиту PromiseKeeper. Идея интересная, но похоже, что работу над проектом остановили после публикации статьи.
#async #js #experimental
https://swizec.com/blog/finding-unresolved-promises-in-javascript/
Свизек Теллер написал статью про ошибки, приводящие к возникновению необработанных промисов — "Finding unresolved promises in JavaScript".
Необработанные промисы — это большой источник проблем, который может привести к крешу программы. Они возникают при забытом перехвате исключения с помощью
catch
, при отсутствующем вызове resolve
/ rejet
или при забытом return
в цепочке промисов.Свизек нашёл научную статью "Finding broken promises in asynchronous JavaScript programs", в которой авторы попробовали автоматизировать поиск подобных ошибок и создали утилиту PromiseKeeper. Идея интересная, но похоже, что работу над проектом остановили после публикации статьи.
#async #js #experimental
https://swizec.com/blog/finding-unresolved-promises-in-javascript/
Swizec
Finding unresolved promises in JavaScript | Swizec Teller
JavaScript is a fantastic server-side language because it's async. That also makes it tricky. 💩 What happens when you swallow errors? Forget to resolve promises? Or run into a number of other anti-patterns