7-я нода зарелизилась, ура! Что нового:
- Движок V8 обновлён до версии 5.4.500.36, в которой обеспечена поддержка 98% возможностей JavaScript, определённых в спецификации ES2015 (ES6) и, частично, будущим стандартом ES2017.
- Отмечается новый парсер URL, соответствующий стандарту оформления URL, подготовленному сообществом WHATWG.
- Доработана работа с Buffer, Child Process, Cluster, файловой системой, промисами
- Полный список изминений
Для меня это долгожданный релиз, так как появилась возможность изпользовать конструкцию async/await без транспайлера babel. Включается это все ключом --harmony.
Теперь можно без babel так:
(async function() {
let content = await require("request-promise")
.get("http://example.com/");
console.log(content);
})()
Еще неделю назад ветка Node.js 6.x получила статус LTS, обновления для которой будут выпускаться в течение 30 месяцев. Выпуск Node.js 8 запланирован на апрель 2017 года.
Я собрал 7-ю ноду для
Комментарии (93)
shasoft
26.10.2016 14:45-1А не появилась возможность запускать Node JS с флешки? Штатно, а не с помощью спец-программ.
apelsyn
26.10.2016 14:54Если речь идет о Windows:
- распаковываем на флешку node-v7.0.0-win-x64.zip или node-v7.0.0-win-x86.zip
- запускаем, все работает.
justboris
26.10.2016 15:21-6Теперь можно без babel так
Можно, но конкретно так лучше не писать.
С Promise получается короче:
require("request-promise") .get("http://example.com/") .then(content => console.log(content))
Во-вторых, с инлайновой async-функцией может возникнуть конфуз
(async function() { let content = await require("request-promise") .get("http://example.com/"); console.log("1"); })() console.log("2");
В консоли будет
2 1
Что не совсем очевидно при чтении кода, хоть и понятно почему это происходит.
Yeah
26.10.2016 15:27-7Касательно последнего примера: разве не в этом суть асинхронности? Честно говоря, меня забавляет, когда нодеры сначала долго рассказывают, как круто, что у них есть асинхроннсость, а потом придумывают костыли типа promises, чтобы таки писать синхронно.
Odrin
26.10.2016 15:38+11Promise — это не костыль «чтобы таки писать синхронно», а способ избавиться от callback hell и структурировать асинхронный код.
HelpOP
26.10.2016 16:35+3Вы не смотрите в корень проблемы. А конкретно почему возникает callback hell?
apelsyn
26.10.2016 16:58+3Покажите мне цикл на промисах, чтоб я асихронно получал пользователя из базы далее что-делал полученными данными и запрашивал следующего пользователя.
Слабо?
boolive
26.10.2016 17:05-2Промисы позволяют применить async/await или генераторы, и получите циклы с виду синхронные.
justboris
26.10.2016 17:20А цикл бесконечный? Как запрашивается пользователь? Если у них id по порядку, то я просто могу пробежаться for-циклом и сделать запрос для каждого id.
Давайте немного не так: вы приведете пример кода с использованием async-функций, а мы попробуем переписать без него без потери в читаемости.
UPD. Нашел ваш коммент. Попробую что-нибудь сделать.
JustFailer
26.10.2016 17:23-1const usersList = getArrayOfUsersSomehow(); let usersChain = new Promise.resolve(); usersList.foreEach( (user) => { usersChain = usersChain .then( () => doSomethingWithUser()); });
Что-то подобное? Не спора ради, просто интересно.apelsyn
26.10.2016 17:25Напишите аналог на промисах, у вас тут "независимая" обработка кажного юзера.
seryh
26.10.2016 17:38+3let user,spammers = []; (function loop() { getUser().then((user) => { isSpammer(user).then((user) => { spammers.push(user); if (spammers.length <= 10 && user !== null) loop(); }); }); }())
А зачем оно вам? async/await безусловно куда более лучшие инструменты чем promise.
Aries_ua
26.10.2016 21:21+2Покажите мне цикл на промисах, чтоб я асихронно получал пользователя из базы далее что-делал полученными данными и запрашивал следующего пользователя.
В данном предложении содержится просто противоречие. Вы хотите получить пользователей асинхронно, а потом синхронно что-то с ними сделать. Это как? Смысл тогда какой? Асинхронно стоит выбирать, что бы потом, так же что-то с ним сделать. Возможно я не понимаю вашу мысль. Можете более детально расписать? Я тогда сделаю для вас решение.apelsyn
26.10.2016 21:27+1В том то и дело что async/await выглядит как синхронный код а выполняется асинхронно.
Другими словами когда вы ждете ответа с базы вы не блокируете поток. В этот момент ваше приложение может обрабатвать другие запросы от пользователей.
enniel
26.10.2016 15:42+3Только вот с промисами код всё равно не становится синхронным, он остаётся асинхронным, только выглядит получше.
lsknwns
26.10.2016 16:41+2Во-первых эти «костыли» никакого отношения к нодерам не имеют, это практически стандарт языка.
Во-вторых, в стандарт эти «костыли» запиливаются не по желанию тех, о ком вы говорите, а как раз по желанию тех, кто не они, чтобы облегчить им всю тягость бытия вкатывания в язык, ибо как альтернативы нет, а им так сложно разобраться и вообще во всех бедах виноват молоток, а не человек его использующий.
Собственно если рассматривать под 'нодерами' фанатов языка, то они как раз страдают от лишней перегруженности, которая в общем-то и не нужна (cv. class), потому что 'нефанатам' сложна.
BoryaMogila
26.10.2016 15:42+5С промисом короче если у тебя один асинхронный запрос, а если у тебя 2 и больше асинхронных запроса, то на с async/await это:
(async function() { const request = require("request-promise") let someData = await request.get("http://example.com/"); let anotherData = await request.get("http://example2.com/"); // манипуляции с данными console.log(/*результат манипуляций*/); })();
а с промисом:
const request = require("request-promise") request .get("http://example.com/") .then((someData) => { request .get("http://example.com/") .then((anotherData) => { // манипуляции с данными console.log(/*результат манипуляций*/); }) }
ничего не напоминает))justboris
26.10.2016 15:43-1Ваш пример лучше. Мой комментарий был про то, что в статье пример использования async-функций высосан из пальца и никакой полезности не показывает.
Yeah
26.10.2016 16:13В вашем примере для await, если каждый запрос выполняется ровно за секунду, то через какое время выполнится console.log?
Galiaf47
26.10.2016 16:23+3Извиняюсь если допустил ошибку, но я написал бы немного по другому
const request = require("request-promise") request .get("http://example.com/") .then((someData) => { return request .get("http://example.com/") }) .then((anotherData) => { // манипуляции с данными console.log(/*результат манипуляций*/); }
justboris
26.10.2016 16:27+5А я бы вообще через Promise.all сделал, чтобы было параллельно
const request = require("request-promise") Promise.all([ request.get("http://example.com/"), request.get("http://example2.com/") ]).then(([a ,b]) => { console.log(a + b); })
Конечно это сработает, только если второму запросу не нужны данные первого. Если нужны, то async-functions FTW.
brusher
26.10.2016 17:30+1Если я не ошибаюсь — вы потеряли someData к моменту манипуляции с данными.
А вот вариант с Promise.all — в данном случае лучший, если только второй запрос не требует информации из первого :)
bertmsk
26.10.2016 16:27+2Это обычный promise hell. Обещали решить с применением политиканов (politicians)
shmidt_i
26.10.2016 16:39const request = require("request-promise") request .get("http://example.com/") .then((someData) => request.get("http://example.com/")) .then((anotherData) => { // манипуляции с данными console.log(/*результат манипуляций*/); })
В этом и смысл — сделать код более плоским
inker
26.10.2016 16:39+1Зачем ждать, пока выполнится первый реквест, чтобы запустить второй?
(async function() { const request = require("request-promise") const [someData, anotherData] = await Promise.all([ request.get("http://example.com/"), request.get("http://example2.com/") ]) // манипуляции с данными console.log(/*результат манипуляций*/); })();
const request = require("request-promise") Promise.all([ request.get("http://example.com/"), request.get("http://example2.com/") ]).then(([someData, anotherData]) => { // манипуляции с данными console.log(/*результат манипуляций*/); })
walkman7
26.10.2016 17:24Затем что нужны ___последовательные___ запросы (следующий запрос зависит от предыдущего).
apelsyn
26.10.2016 17:29Чтоб не блокировать исполнение других обработчиков. Например к вашему web-серверу пришло несколько запросов.
alek0585
26.10.2016 18:33Возможно ли, что в таком случае имеет место неграмотная архитектура?
VolCh
27.10.2016 10:05Возможно, но возможно и нет. Например, второй запрос должен содержать результаты первого или первый запрос — проверка прав на отправку второго.
Alternator
27.10.2016 10:39Возможно всё
Но нормальные юзкейсы со строго последовательным асинхронными операциями также существуют:
1. Операция сейва в редакторе
— подготовка превью-картинки
тут может быть параллельно еще какая-то подготовка мета-данных
— упаковка в архив
— пересылка на сервер
— опционально показ красивого(не-alert) модального окна по завершении
2. массовые операция редактирования/анализа кучи файлов
в целом операции будут идти параллельно(либо в очереди с заданным лимитом прааллельности)
но для отдельного файла будет последовательный набор шагов
— прочитать файл
— провести изменение/анализ файла
— записать файл
3. система макросов для приложения.
так как некоторые пользовательские операции вынуждены быть асинхронными, то и система макросов становится асинхронными(но строго последовательными)
Вот тут из моей практики async..await превращает код вообще в песню, по-сравнению с колбеками, или даже чистыми промисамиmata
30.10.2016 16:24-1макросы? откуда в js макросы?
staticlab
30.10.2016 21:49Имеются в виду не те макросы, которые в Си, а те, которые макрокоманды в прикладных программах.
Alternator
31.10.2016 15:10да, подразумевались макрокоманды как в офисе, либо других прикладных программах.
но в javascript-е могут быть и макросы как в C
1) Вот плагин babel-а, в котором я участвую — https://github.com/codemix/babel-plugin-macros
но тут скорее о макросах, как об инлайновых функциях
2) Также есть отдельная надстройка синтаксиса — http://sweetjs.org/
тут наверно можно гораздо шире определить макросы
Vladimir37
26.10.2016 16:39Нет. С промисами вот так:
Promise.all([request.get("http://example.com/"), request.get("http://example2.com/")]).then((dataFirst, dataSecond) => { // манипуляции с данными console.log(/*результат манипуляций*/); });
neoxack
26.10.2016 17:21-1(async function() { const request = require("request-promise") let someData = await request.get("http://example.com/"); let anotherData = await request.get("http://example2.com/"); // манипуляции с данными console.log(/*результат манипуляций*/); })();
Лучше так:
let result = await Promise.all([request.get("http://example.com/"), request.get("http://example2.com/") ]);
overherz
26.10.2016 16:39по-моему здесь как раз все очевидно, async/await так и должен работать
justboris
26.10.2016 16:59-1Конечно очевидно, если медленно и внимательно читать 5 строчек кода.
Но представьте, как это будет выглядеть в реальном проекте, где кода больше
(async function() { let content = await require("request-promise") .get("http://example.com/"); doSomething(); if(a !== b) { doSomethingElse(); } // ... // и еще много-много кода // ... console.log("1") })() console.log("2");
Пока дочитаешь до конца, можно потерять контекст и ошибиться. А с Promise и коллбеками граница синхронного и асинхронного кода четче и понятнее.
apelsyn
26.10.2016 16:48А если в цикле?
justboris
26.10.2016 17:00А можете привести пример кода? Без него непонятно, что вы имеете в виду.
apelsyn
26.10.2016 17:19let user,spammers = []; do { user = await getUser(); if (await isSpammer(user)) { spammers.push(user) } } while (spammers.length <= 10 && user !== null); console.log(spammers)
Ну и все это, конечно, внутри асихронной функции.
justboris
26.10.2016 17:33function collectSpammers(spammers) { if(spammers.length > 10) { return spammers; } return getUser() .then(user => { if(!user) { return spammers; } return isSpammer(user).then(spammer => { if(spammer) { spamers.push(users); } return spammers; }); }) .then(() => collectSpammers(spammers)) } collectSpammers([]).then(spammers => console.log(spammers))
Согласен, получилось не так аккуратно как с async, но ведь реализуемо! Сомневаюсь, что нужно писать такой код регулярно, и поэтому async так уж необходим в стандарте
f0rk
26.10.2016 17:58Если spammers.length <= 10 && user == null он вроде бы продолжит выполняться
justboris
26.10.2016 18:05Почему вы так считаете? Есть же проверка сразу после getUser.
f0rk
26.10.2016 18:11getUser().then(u => { if (!u) return spammers })
Зарезолвится с массивом spammers, потом вы вызываете.then(() => collectSpammers(spammers))
, и процесс зациклился, пока getUser() возвращает null следующий в цепочке then будет вызывать collectSpammersjustboris
26.10.2016 18:17Действительно, спасибо за замечание! Поправил:
function collectSpammers(spammers) { if(spammers.length > 10) { return spammers; } return getUser().then(user => { if(!user) { return spammers; } return isSpammer(user) .then(spammer => { if(spammer) { spamers.push(users); } return spammers; }) .then(() => collectSpammers(spammers)); }) } collectSpammers([]).then(spammers => console.log(spammers))
f0rk
26.10.2016 18:52Ок, раз уж пошла такая пьянка, добавлю свой вариант :)
function collectSpammers(n) { const spammers = []; return Array(n).fill(0).reduce(m => m .then(() => getUser() .then(function check(u) { if (u === null) return Promise.reject(); return isSpammer(u).then(spammer => { if (spammer) spammers.push(u); else return getUser().then(check); }); })), Promise.resolve()).then(() => spammers, () => spammers); } collectSpammers(10).then(spammers => console.log(spammers));
inook
28.10.2016 14:38function collectSpammers(_users) { return _users.reduce((promise, _user) => { return promise.then((prevUsers = []) => { const user = User.findById(_user); return Promise.all([...prevUsers, user]); }) }, Promise.resolve()); };
apelsyn
26.10.2016 18:06+1А если вам нужно проверить не случилось ли ошибки при получении данных из базы
try {
user = await getUser();
} catch (err) {
// Error handling
}
Вы представляете во что превратиться Ваш код?
async/wait это отличная конструкция для написания человек-читаемого и легко понимаемого кода. Потому что код выглядит как синхронный а виполняется асинхронно.
Ваше заявление "С Promise получается короче" работает только для примитивных конструкций, для более сложных это не всегда справедливо
justboris
26.10.2016 18:12А если вам нужно проверить не случилось ли ошибки при получении данных из базы
Вы представляете во что превратиться Ваш код?Примерно в то же самое, во что и ваш. Добавится пара конструкций.
Ваше заявление "С Promise получается короче" работает только для примитивных конструкций
Согласен. Но в статье вы привели именно такую конструкцию, на что я и обратил внимание. Чтобы показать хорошие стороны async можно было сразу привести пример про спаммеров, а не тривиальный request.
kurtov
26.10.2016 18:39let spammers = []; getUser() .catch(onGetUserErrorHandler) .then(getSpammer) .then(() => console.log(spammers)); function getSpammer(user) { if (user === null) { return; } if (spammers.length === 10) { return; } return isSpammer(user) .then((isSpammer) => isSpammer && spammers.push(user)) .catch(onSpammerCheckErrorHandler) .then(getUser) .catch(onGetUserErrorHandler) .then(getSpammer); }
indestructable
26.10.2016 20:18then после catch не правильно, если, конечно, не хотите попасть в оба.
kurtov
27.10.2016 09:21если возникнет ошибка с одним юзером, то перейдем к следующему, а не завершим работу
alek0585
26.10.2016 18:42```
var user, spammers = [];
function load () {
return getUser().then(function (user) {
if (isSpammer(user)) {
spammers.push(user);
}
return user;
});
}
var array = _.map(_.range(0, 10), function () {
return load;
})
utils.sequence(array).then(function () {
console.log(spammers);
});
```
enniel
26.10.2016 15:39Для debian-based дистрибутивов можно установить так:
curl -sL https://deb.nodesource.com/setup_7.x | sudo -E bash - sudo apt-get install -y nodejs
Доку пока ещё не обновили, может и под другие дистрибутивы уже можно установить.asdf404
26.10.2016 17:52Ещё можно использовать NVM:
nvm install v7.0.0 nvm alias default v7.0.0
iShatokhin
27.10.2016 08:03+1Можно даже так (если фиксирование минорной версии не критично):
nvm install v7 // поставится последняя доступная v7 nvm alias default v7 // дефолтной всегда будет самая свежая из установленных 7-ок, не нужно будет постоянно подправлять минорные версии после обновления
saggid
27.10.2016 19:34Скажите пожалуйста, как вы решаете проблемы с nvm и подобными библиотеками для установки библиотек, когда например ты установил своему пользователю какую-то версию node.js, а потом из под банального
sudo {cmd}
эта нода уже недоступна? Та же проблема с rvm, к примеру. Или другой случай: надо запускать по крону какой-то баш скрипт, которому тоже эта Node.js нужна. Там тоже обычно приходится немного извращаться, подключая в начале скрипта нужные файлы из папкиnvm
.
Ставить глобально через какой-нибудь
apt
по-моему удобнее всё-таки, чем таким образом. Хотя и менее гибко.asdf404
27.10.2016 19:50Ни разу не приходилось запускать node с sudo за время использования nvm, а до этого приходилось лишь пару раз. Но, если бы пришлось, то скорее всего прописал бы полный путь до бинарника (
sudo ~<username>/.nvm/versions/node/<version>/bin/node
). Да, неудобно, но если это не разовый запуск (например крон), то можно создать симлинк в/usr/bin
или создать алиас или скрипт:
#!/path/to/node console.log('Hello World!')
Сейчас вообще стараюсь не запускать проекты на хост-машине напрямую. Толкаю всё в докер, а с хост машины дёргается
docker-compose exec some-periodic-task node /src/task.js
— криво, неудобно, но лучше не придумал.saggid
28.10.2016 03:23Неудобен такой подход, с прямой ссылкой на какой-то бинарник node.js в nvm. Обновишь ноду — и все скрипты исправлять свои? :) Если идти такой дорогой, то к баш-скрипту лучше подключать код загрузки .nvm из .bashrc:
export NVM_DIR="/home/{username}/.nvm" [ -s "$NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh" # This loads nvm
Тогда будет загружаться текущая активная Node.js.
Возвращаясь к глобальной установке установщиков библиотек. На тему Node.js я могу сам за себя ответить, ибо нашёл способ установить nvm глобально на машине:
wget -qO- https://raw.githubusercontent.com/xtuple/nvm/master/install.sh | sudo bash
Но блин. В мире-то не только NVM существует… Для каждой библиотеки такой форк искать на гитхабе? :) В общем, для себя я пока ничего лучше какого-то свеженького
ppa
или последнего дистрибутива своей ОС не нашёл.ChALkeRx
28.10.2016 04:37+1xtuple/nvm
Эм. Вообще-то, апстрим
creationix/nvm
, зачем вы устанавливаете старый форк какой-то компании?
В nvm было довольно много изменений с тех пор.
saggid
28.10.2016 04:56Ну дык будьте хоть немножечко более внимательны, я достаточно разъяснил всё в своём сообщении. Это не просто форк, а изменённый инсталлер. Почитайте хоть описание к нему, написано же всё.
saggid
28.10.2016 05:01В чём вы только правы — это вполне возможно что nvm будет очень старый, да. Я думал, этот скрипт как-то подтягивает последний nvm и устанавливает его глобально.
boolive
26.10.2016 15:39+1import/export когда будет?
bromzh
26.10.2016 16:06+1А в стандарте уже прописано, как резолвить пути в этих операторах? Т.е. если мы напишем:
import { foo } from 'foo'; import { bar } from './bar';
откуда будут импортированы эти объекты?
С require всё понятно — это чисто нодовская функция, она завязана на систему модулей ноды и node_modules.
Но стандарт ecma не должен завязываться на какую-то конкретную реализацию и должен как-то предусмотреть различные платформы. Ведь в браузере "нет node_modules".
lucky_libora
26.10.2016 16:18гугл на одном из недавних выступлений сказали, что пока этого в движке V8 нет
bromzh
26.10.2016 23:06Так а разве в стандарте есть описание (хотя бы черновик) того, как именно нужно будет резолвить модули? Пока определились только с синтаксисом импортов/экспортов. А пока стандарта нет, в движок нечего добавлять.
indestructable
26.10.2016 16:28Резолвить по тем же правилам, что и пути в
require
. Сделали бы хоть простейшую поддержку в виде трансформации в require/module.exports.bromzh
26.10.2016 23:28+3Можно, конечно, включить это в ноду напрямую. Люди начнут писать под ноду программы, используя нативные импорты (т.е. в npm-пакет попадёт не common-модуль (с require и module.exports), а es6-модуль с import/export).
А потом примут стандарт, и окажется, что резолв модулей как в require не совсем совместим с принятым стандартом. Что тогда делать? Уже написанные программы не будут работать на новых версиях ноды, новые программы не будут работать на тех версиях ноды, где была неправильная нативная поддержка модулей. Представьте, как весело станет управлять зависимостями, если часть из них написаны по-старой схеме, часть по-новой.
Именно для этого и есть babel. Добавить или удалить плагин в бабеле просто, а вот менять версию ноды уже тяжелее. Когда ситуация с модулями прояснится, тогда и нужно будет начинать внедрять, но не раньше.
VolCh
27.10.2016 10:14+1Для трансформаций есть babel, он хорошо делает свою работу, зачем дублировать эту функциональность в Node.js, при том, что с большой вероятностью её потом нужно будет выпиливать?
indestructable
27.10.2016 11:07Да в том-то и дело, что хотелось бы без babel. Он, конечно, крутой, но все-таки отсутствие компиляции круче, чем самая крутая компиляция.
VolCh
27.10.2016 14:20Сделали бы хоть простейшую поддержку в виде трансформации в require/module.exports.
А это не компиляция будет?indestructable
27.10.2016 17:35Технически, конечно, компиляция (или интерпретация). Компьютеры пока не научились джаваскрипт исполнять непосредственно, поэтому, совсем без компиляции/интерпретации не обойтись, очевидно :)
Я имел ввиду компиляцию джаваскрипта перед запуском на Node.
AndreyRubankov
26.10.2016 16:32+2Понимаю, что сейчас будут дико минусовать карму, но: Зачем?((
1. Зачем вводить функционал до того, как он появится в стандарте (это еще draft на es2017)?
2. Зачем вводить async/await на уровне языка, учитывая, что это всего лишь сахар для промисов?
вот завтра окажется, что «async/await» — это плохо, а поддерживать эту фичу придется до конца жизни ES.staticlab
26.10.2016 16:47Ну так реализована экспериментальная поддержка в движке v8. В самой ноде активируется только по ключу --harmony.
- Цель — избавиться от promise hell.
AndreyRubankov
26.10.2016 17:10Цель благородная, но я к тому, что завтра появится async/await hell и быть беде. Если Promise API можно просто выкинуть и забыть (заменить на что-то новое), то async/await из спецификации уже не выкинешь.
Мой поинт о том, что не стоит вносить на уровень языка фичи главная цель которых сделать код красивее.serf
26.10.2016 17:15-1Мой поинт о том, что не стоит вносить на уровень языка фичи главная цель которых сделать код красивее.
Хороший поинт, инженерный подход, но к сожалению вся суть развития EcmaScript относится к "деланию кода красивее", в отличии от допустим TypeScript.
dimaaan
26.10.2016 23:17async await впервые появился в c# в 2012 году и за 4 года не заработал себе плохой репутации.
да и вообще, как вы себе представляете async/await hell?
можно пример?AndreyRubankov
27.10.2016 08:27> как вы себе представляете async/await hell?
Как жуткое хитросплетение синхронных и асинхронных функций.
Как асинхронные функции, которые будут отдаваться наружу как результат выполнения
… и await await func() как следствие.
Как асинхронные функции в качестве параметров для тех же промисов или еще чего-то.
— проблема все та же = незнание как написать хорошо, порождает hell.
> async await впервые появился в c# в 2012 году и за 4 года не заработал себе плохой репутации.
Я могу ошибаться, но проблем с этим подходом не на много меньше, чем с обычным многопоточным программированием, просто эти проблемы сделали неявными.
Все те же await await func() и манипуляции с контекстом.
Да эти все «минные тропы» уже через месяц проходятся довольно просто, но не стоит забывать, что месяц — это у хорошего специалиста, который уже познал горя с многопоточностью.
Да и в C# вам множество тулов поможет и подскажет где вы не правы. В то время, как в ES это можно будет узнать только в рантайме и порою даже только на продакшене.
ps: я за развитие языка, но я против добавления Сахара ради сахара.Alternator
27.10.2016 10:26Хотелось бы узнать больше об этих минных тропах.
с обычными callback-ами мне доводилось сталкиваться с тремя проблемными анти-патернами:
1) асинхронная функция содержит некоторое количество синхронного кода
если он упадет, асинхронная функция никогда не вернет результата.
весьма пакостный для отладки случай.
— чистые промисы решают эту проблему не полностью, если использовать их как попало
2) асинхронная функция делает что-то еще после вызова callback
— странно что-то делать после того как вернул результат.
— этим что-то может оказаться повторный вызов callback(например сразу после if-а), что приводит к двойному старту последующего кода
— но для этой ошибки есть правило в eslint)
— промисы решают эту проблему
3) асинхронная функция вызывает callback на самом деле синхронно(например данные из кэша)
— может порождать дивные стектрейсы в случае падения в колбеке(захватится уже «выполненная» функция не имеющая отношения к падению)
— при попытке решать первую проблему try..catch-ами, приводит ко второй проблеме — err-callback будет вызван еще раз
— логика сложнее в отладке, так как нарушен контракт
— промисы решают эту проблему
Использование async..await автоматически фиксит все 3 проблемы, даже не допуская возможности так ошибиться
И единственный встреченный минус: стектрейсы при отладке все еще не синхронные)
Ну и дополнены обертками от babel
Поэтому интересуют какие проблемы сохранили/создали async..await-ы?
Особенно в контексте того что, в C# есть способы ранней проверки анти-патернов.
Я бы с удовольствием написал бы пару правил для статического анализа в eslint
apelsyn
26.10.2016 16:53Это не драфт, предложение находится в Stage 3 ("Candidate"), в следующем месяце будет частью стандарта Stage 4 ("Finished").
alibertino
26.10.2016 16:59Потому что, по сути, это единственный путь рождения и проверки немертворожденных стандартов. А по поводу поддержки, это не обязательно, можно объявить deprecated. Поэтому и запускается не в LTS-версии.
ChALkeRx
27.10.2016 13:14+4Node.js 7.0.0 зарелизился. Встречайте async/await без babel
Включается это все ключем --harmony.Эээ. Напомню ещё раз:
--harmony
в продакшне использовать не стоит, и привязываться к его фичам — тоже.
Пока что рекомендованный способ сделать себе async/await — это таки babel.
98% возможностей JavaScript, определённых в спецификации ES2015 (ES6)
Это и в v6 LTS было. Причём отставшиеся 2% — PTC.
prog666
Я слышал что в v8 54 есть утечка памяти при использовании async await. ждем пока включат 55
rumkin
Нужны подробности. С чего вы взяли что утечку будут фиксить только в 55 версии? Возможно уже устранили или только в браузере проявляется?
Leopotam
https://github.com/nodejs/promises/issues/4#issuecomment-254159118
kurtov
Release V8 5.5 24 октября (два дня до выхода node 7). В этом релизе представлены async\await функции.
Баг с утечкой исправлен 16 сентября, v8 5.4 был зарелизен 9 сентября