Комментарии 18
Если не ошибаюсь — еще с 6.* с --harmony было.
2. Для оборачивания callback кода есть util.promisify
3. Возвращать объект с ошибкой и полезными данными — ИМХО очень плохо. async-await позволяет обрабатывать ошибки в асинхронных функциях в try-catch
4. А вот это вообще ни в какие ворота
var files = ['1.csv', '2.csv', '3.csv'];
var results = [];
// всех вызываем
for(let i = 0;i<files.length;i++){
results.push( promise(fs, fs.readFile, files[i]) );
}
// а потом дожидаемся всех (при это все 3 могут придти одновременно, тоесть не нужно ждать каждый отдельно. Если третий прочитается быстрее чем первый, он уже будет готов )
for(let i = 0;i<files.length;i++){
results[i] = await results[i];
}
используйте developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Global_Objects/Promise/all
FYI пакеты, которые предоставляют promise-api:
www.npmjs.com/package/mysql2
www.npmjs.com/package/request-promise-native
www.npmjs.com/package/fs-extra
2) promisify отдаст нам then и catch, что лично для меня выглядит как колбэк
3) try/catch слишком накладно для realtime под нагрузкой
4) ну извините) есть некоторые цели, например когда несколько разных запросов мы хотим выполнить параллельно, а результат отрабатывать постепенно. Например в случае с базой там могут использоваться транзакции, которым по какой то причине иногда нужно делать rollback. Так что по ситуации, для моего способа есть определенные "ворота"
const {promisify} = require('util');
const {readFile} = require('fs');
const readFilePromise = promisify(readFile);
async run() {
const fileData = await readFilePromise('./package.json', 'utf8');
}
run().catch(console.error);
3. Если нагрузка такова, что try-catch играет роль — это задача ИМХО не для NodeJS. При таком подходе (предложенном вами) читаемость сильно страдает.
4. Не понял чем мешает Promise.all. Если выполняется несколько запросов к бд внутри транзакции, то что мешает сделать что-то вроде (не уверен, кстати, будет ли это вообще иметь смысл, т.к. возможно внутри транзакции все запросы выполняются последовательно)
try {
// только если запросы между собой независимы, что бывает далеко не всегда.
const result = await Promise.all(arrayWithDBQueriesPromises);
await transaction.commit();
} catch() {
await transaction.rollback();
}
в сетевых запросах, в чтении файлов и множестве других сценариев, Promise.all вообще не мешает, а только помогает.
4) Await в цикле чтобы не дожидаться остальных запросов (как это делает promise.all), если на каком то этапе нужно все отменить.
3) вот тут достаточно убедительно https://m.habrahabr.ru/company/ruvds/blog/334806/
4) внутри транзакции могут быть не только запросы к базе, но и запросы в микросервисы или сторонние апи. В ситуации, когда всё работает — ваш вариант правильнее. Если что-то отваливается внутри — то мой вариант практичнее
Однако, в Node 8.3+ вызов функции из блока try на производительность практически не влияет.
И еще раз. Программы пишутся в первую очередь для людей. Я нигде не видел, что бы подход, приведенный вами практиковался в JS, зачем усложнять жизнь другим программистам?
Да, try-catch может влиять на производительность, если это узкое горлышко, то задача не для NodeJS.
4) Promise.all возвращает результат (либо в .catch(), либо в try-catch(e) {} ) если хотя бы один из промисов вернул ошибку, и не надо будет дожидаться всех остальных.
Точно так же я не видел чтобы использование try/catch являлось хорошим тоном в продакшне. Если можно обойтись без него — буду обходиться без него. Зачем полагаться на исключение и ждать его, если простой проверкой можно предотвратить?
Нет, это не узкое горлышко, но одна из оптимизаций, как в плане производительности так и в плане качества.
Промис вернет ошибку на уровне метода, а не на уровне логики (обработки результата запроса)
Я не говорю что лучше а что хуже. Я говорю что в каждой конкретной ситуации/проекте/компании могут применяться свои методы. И любой из вариантов имеет право на жизнь.
8.3 еще небыло
Это о NodeJS?
тогда советую проверить nodejs.org/en
8.9.1 уже в LTS, и 9-я подоспела.
Речь шла про пол года назад.
Статья опубликована сейчас. И комментарий вы писали сейчас, а не пол года назад.
1. Я не считаю try-catch целесобразным ВЕЗДЕ, но придумывать какие-то механизмы, что бы их не использовать, но возвращать ошибку в качестве второго аргумента, и не использовать механизмы, которые предоставляет язык, это я считаю неверным. Как я уже писал причина — в языке используются другие подходы для обработки ошибок и, я уверен, большая часть программистов, привыкла использовать их, а не придуманные решения только что бы не использовать try-catch т. к. это часть оптимизации (по факту — микрооптимизация, высока вероятность, что в будущем этот механизм в V8 будет оптимизирован еще сильнее).
2 — Приведенная вами конструкция, призванная заменить Promise.all — опять же зачем, если есть инструмент языка, зачем эти велосипеды?
// Вместо
let totalPrice = 0;
for(let i = 0; i < prices.result.length; i++){
totalPrice += prices.result[i].price;
}
// Просто
let totalPrice = 0;
prices.result.forEach((item) => totalPrice += item.price);
// Или чуть более изысканно
let totalPrice = prices.result.reduce((total, item) => total + item.price, 0);
Выглядит прямо как в php.
Имхо, это не тот идеал, на который надо ровняться.
Пока callback-ами обхожусь, но надо конечно переходить на async.
Не то что бы принципиально… некоторый код полностью дублируется на клиенте, а там натив без всякий babel и прочего. А поддержка пока не сильно. Полифилы без сборщиков подключать слишком много гемороя.
Есть, но пока все крайне сырое :(
Observable на уровне языка (сейчас можно просто использовать rxjs)
Я хотел на выходных написать статью о ReasonML, но у меня стандратный пример не компилировался, а просто переводить документашку не интересно, так что пока ждем.
Про паттерн матчинг — пусть покажут хоть какую-то реализацию (да и это будет актуально интересно только для deep pattern matching)
ReasonML нафиг не нужен! Еще один способ сделать OCaml еще хуже по виду. Для жаваскриптеров же есть Elm, Purescript
Используем async/await в nodejs уже сегодня