Обновить
2
0

Пользователь

Отправить сообщение
Какие-то конкретные юзкейсы есть, где не работает?
Фигурные скобки вроде как тоже гарантируют полное чтение.
По-крайней мере я так до сих пор думал.
Какие именно интересные эффекты меня подстерегают при их использовании в данном юзкейсе?

Также интересно, для каких юзкейсов нужно явное указание кода последнего выхода $?
Вроде и без него код автоматически подхватывается. Или такое поведение актуально не для всех версий bash?
Круглые скобки в отличии от фигурных порождают под-процесс, хотя надобности в нем нет
Жаль что в статье не обозначен ни один из способов, как избежать этой проблемы

Вот один из вариантов:
#!/bin/bash

{
  # код тут
}; exit;

Интерпретатор принудительно прочитает скрипт до закрывающей фигурной скобки, включая команду exit(важно, чтобы она была на той же строке)
Я правильно понимаю, что глобальное отключение звука пока можно сделать только вручную передавая везде soundEnabled?
Думаю было бы уместно сделать контекстный провайдер для глобального отключения звука

И еще интересная мысль на развитие:
Провайдер темы, где в каждой теме бы содержался хэш <имя эффекта, путь к файлу>, и вызывать хук с именем эффекта

PS извините, не увидел что это перевод, и это обсуждение тут не совсем уместно
Пункт про перемешивание является вредным
Он неправильный(это перемешивание не истинно случайное), и медленный(O(n*lg n) вместо O(n))
habr.com/ru/post/358094

UPD: глянул в оригинал. При переводе потерян весь смысл в «Every day I'm shufflin'». Автор неспроста написал этот текст жирным

В yarn можно задать в рамках вашего package.json-a
https://yarnpkg.com/lang/en/docs/package-json/#toc-resolutions


Кроме того, в рамках yarn можно массово слить дубликаты в yarn.lock, если их версии перекрываются — https://github.com/atlassian/yarn-deduplicate
Вручную слить одиночные дубликаты(с перекрывающимися версиями) в рамках yarn.lock тоже не сложно

Хотя кажется что все что работает в браузере(Chrome), будет работать и в electron — это не совсем так.
Например window.open работает с другим API, и даже если сделать nativeWindowOpen он не будет полноценно работать
В случае использования авторизации через фейсбук, у открываемого окна не будет доступен window.opener, что ставит крест на возможности авторизации(хотя для electron@2 есть воркэраунд)

Других значимых отличий по части браузерной работы я за полгода пока не нашел
Что вы скажете о скорости? У вас быстро файлы трансформируются?

Когда я плотно этим занимался, я не задумывался и не сравнивал скорость этих режимов.
Просто принял его как данность, и исправлял плагин с учетом коллизий
Сейчас у меня нету проектов где я плотно использую babel, поэтому особо не на чем сейчас проверить
Можете сами поэксперементировать. Опция для переключения режима — passPerPreset

Как выглядел этот апи? Я не нашел об этом информации.

visitors.merge из пакета `babel-traverse`
Документации по нему я не видел. Наверно откопал в дебаге, или подсмотрел в базовых плагинах
Да, это действительно медленее, вы уверены, что babel и eslint объединяют параметры всех визиторов и обходят их за один проход?

Для babel 5-ой версии параллельный обход всеми плагинами был штатным способом.
И был отдельный ключ(не помню для CLI, или babelRc), который гонял плагины последовательно
И в сложных плагинах(когда замена производилась не для текущей ноды) паралельный обход создавал трудности
Хотя кроме воркэраунда с опцией был еще вариант повесить плагин на Program:exit, и совершить траверс самостоятельно, но это не оптимально и не рекомендовалось

Кстати апи по мержу визиторов в один удобно было использовать для разбития одного плагина на несколько логических частей для упрощение поддержки

А вот в текущем babel, и eslint я не знаю как сейчас организована работа
Eslint умеет исправлять ошибки, хотя его API и несколько ограничено/непривычно по сравнению с трансформациями babel

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

Плагин сам вызывает traverse. Тут есть и плюсы и минусы:
1. Каждый плагин выполняет свой traverse, что медленнее чем один комбинированный traverse, выполненый ядром
2. Трансформации делаются последовательно, и не могут конфликтовать с другими плагинами.
Параллельные трансформации — не самая легкая в разработке и отладке вещь.
2.1. Но и взаимодействовать они также не могут, и их работа зависит от порядка. Например если сперва вызывается плагин удаляющий пустые блоки, а только потом удаление debugger/console.log, после чего могут остаться пустые блоки, которые уже не будут удалены
Полагаю для разделения масла и воды их плотности и сила гравитации играют роль только в вопросе «кто всплывет, кто потонет».
А сам механизм разделения обоснован исключительно силой поверхностного натяжения, и несмачиваемостью.
Если налить в блюдце воды, и капнуть пару капель масла на поверхность, то при встрече они слипнутся, и сила тяжести тут не при чем.
Так что и в отсутствие силы гравитации масло с водой разделятся
В том смысле что можно обрабатывать одновременные операции ввода/вывода в одном потоке, в событийном цикле, как это происходит в ноде?
Если да, звучит здорово.
Если же под отдельную операцию ввода/вывода нужно взять отдельный поток из пула, и работать с этой задачей асинхронно, то в плане нагрузки вроде ничего не меняется.
Нет, это вполне себе улучшение.

С чем сравниваем ноду: с CGI/FastCGI, и пулом потоков(как в ASP.NET)

Юзкейс 1 — приложение в котором практически нет сложной вычислительной логики, а только операции ввода/вывода:
1) В CGI на каждый запрос создается и убивается отдельный процесс
Проигрываем на времени создания процесса, на памяти под отдельные процессы, и на переключении контекста между процессами
При этом большую часть времени каждый процесс находится в ожидании одной операции чтения/записи
2) В FastCGI процессы переиспользуются, и достаются/возвращаются из пула по мере необходимости.
Пропали потери на создание/уничтожение процесса, но память и переключение контекста остались
3) Пул потоков. Примерно тоже, что и в предыдущем пункте, только меньше накладных расходов на память и переключение контекста
4) Однопоточная асинхронная архитектура(Node.js, Twisted, ...)
Процесс и поток один. Нету накладных расходов на память и переключение контекста(если не считать соседние и системные процессы).
При условии что нету блокирующих вычислительных операций, все очень хорошо в сравнении с предыдущими пунктами

Юзкейс 2 — в приложении есть блокирующая вычислительная логика
Допустим время одного запроса 1 секунда, из них 0.1 — вычисления, и 0.9 — ожидание ввода вывода. И на сервер приходит в среднем 100 запросов в секунду
1-3) в среднем будет 100 одновременно активных процессов/потоков(с сопутствующими накладными расходами)
4.1) child_process/cluster. В среднем должно хватить 10 воркер-процессов, каждый из которых будет на 100% занят вычислениями(в перерывах между ними получая результаты ввода/вывода от других запросов)
Хотя возможна проблема когда приходят два одновременных запроса в один воркер, и тогда второму придется дождаться завершения блокирующей операции от первого запроса(+100мс для конкретного запроса).
Но можно увеличить количество воркеров(не столь значительно как для 1-3 подходов), и уменьшить потенциальный разброс
4.2) То же самое, только уменьшаются накладные расходы на процессы, и обмен сообщениями между ними
Таким образом Node.js и в данном юзкейсе хорошо справляется(используя меньшее количество процессов/потоков)
1) в электроне вам доступны обычные npm-пакеты, например screenshot-desktop
2) в электроне вам не нужно спрашивать у пользователя разрешения для установки расширения
Хотя я не в курсе, встраивается ли оно в инсталляцию. Если не встраивается, то у пользователя может и не установится(например из-за санкций)
И не совсем уверен, будет ли каждое расширение работать(поддержано ли необходимое API для него)
Вот еще одна возможность многопоточности в Node.js — Napa.js
Последний пункт неактуален с появлением React.createRef()
Более популярна для callback-джунглей библиотека www.npmjs.com/package/async
В ней и функциональности больше, да и API на мой взгляд чище.

Кроме того есть ее порт для промисов — www.npmjs.com/package/async-q
Также полезна, так как организация высокоуровневых шаблонов асинхронности(ограничение количества потоков, очереди) в промисах все-таки отсутсвует
В таком случае можно обернуть верхний уровень в авто-вызываемую асинхронную функцию, и обработать ошибку в нем
(async function main() {
    await func1();
    await func2();
})().catch((err) => console.error(err))


Также, вероятно на верхнем уровне асинхронные функции вызываются синхронно, одна за другой, потому что должны идти параллельно и независимо (иначе они уже были бы обернуты в асинхронную функцию, либо цепочку промисов).
Тогда стоит рассматривать эти функции как верхнеуровневые, и достаточно добавить try-catch только в них, либо вообще обработать их ошибки на уровне модуля
func1();
func2();
async function func1() {
  try {
    // ...
  } catch(e) {
    console.log(e);
  }
}
async function func2() {
  try {
    // ...
  } catch(e) {
    console.log(e);
  }
}

func1().catch(e => console.log(e));
func2().catch(e => console.log(e));;
async function func1() {
  // ...
}
async function func2() {
  // ...
}


В итоге try-catch все еще не нужен в каждой асинхронной функции, и мы получаем обработку ошибок на верхнем уровне(и в тех функциях где она нужна по логике приложения)
При этом, если исключения доходят до верхнего уровня, то логично использовать uncaughtException/rejectionHandled
Нужен конкретный пример, где один внешний try-catch не работает
Проверил на базовых примерах — внешний try-catch прекрасно работает

Может сломаться, если не await-ить внутренние вызовы, но тут и try-catch-hell не спасет
Как следствие может сломаться на изощренных юзкейсах, вроде «послать все запросы в цикле, их промисы запомним в массив, а потом в однопоточном цикле их await-ить и обрабатывать»
Но в таких нетривиальных случаях пожалуй лучше будет использовать библиотеки управления потоком, или как workaround, вызвать перед циклом
await Promise.race(results)


Как следствие try-catch-и можно размещать согласно логике приложение(там где вы хотите реально обработать ошибку), например на уровне обработчика запроса — точно также, как это делается для синхронного кода

Информация

В рейтинге
Не участвует
Зарегистрирован
Активность