Comments 54
Так что статья устарела.
На мой взгляд, эти новомодные абстракции безбожно текут, растворяя синтаксический сахар до несъедобного состояния.
Используйте Коллбэки, как завещали Керниган и Ричи. там по крайней мере понятно когда выполняется код.
там по крайней мере понятно когда выполняется код.
Можно подумать, что в промисах непонятно.
а async/await уже пришли?
Да уж давно. Не знаю, правда, как на счёт мелкомягких и мобильных.
async/await удобная штука, но только там где не придется писать часто .then в конечном потребителе.
Можете развернуть мысль?
Завершения любого Thenable можно ждать с помощью await.
Браузеры не поддерживают асинхронные события.
Простите, какие? Из тех, которые у меня стоят — только в 11 IE async/await не распознался.
Да и на ui редко много вложенных асинхронных вызовов.
Знаете, клиентская часть веб-приложения, это далеко не только ui. Вот, у меня тест-плеер. Вопросы подгружаются ajax-ом, и интерфейс проверки ответов тоже асинхронный. Без полноценного promise — никак. Мне пришлось свою обёртку над jQuary-вским deferred писать (требования совместимости с говном триллобита).
private async void button_Click(object sender, EventArgs e)
{
await LongOperation();
}
в js это будет так:
buttonEl.addEventListener(«click», buttonClick, false);
function buttonClick(e)
{
longOperation().then(......);
}
Было бы круто так, но это не поддерживают браузеры:
buttonEl.addEventListener(«click», buttonClick, false);
async function buttonClick(e)
{
await longOperation();
}
Ничего, что async/await напрямую завязаны с работой с промисами? Ничего, что промисы решают огромную вложенность коллбеков (это не надуманная проблема, если что)? Ничего, что промисы более явно инкапсулируют значение, причем это значение можно гибко переиспользовать?
Ну да, х*й с ними с промисами, давайте не читать ничего и не думать, юзать коллбеки и сахар проще.
В том, что это трудно поддерживать. Если вложенность кода (не важно по какой причине — много if-веток, много вложенных функций, много коллбеков, циклов, whatever) — большая, то читать и понимать такой код гораздо проблематичнее. Любая flat сущность мозгом воспринимается в разы проще, чем иерархия.
А в чём проблема с промисами? Это те же самые коллбеки, только чуть по другому оформленные.
Кстати говоря, в некоторых случаях удобно комбинировать.
Вот, например, у меня есть функция handler, которая обрабатывает некоторые ошибки и возвращает для этих случаев валидный результат.
let result = await get('условный запрос').catch(handler);
Предполагается, что функция handler вернёт валидное значение в случае предусмотренных ошибок, и бросит без изменений непредусмотренные.
промисы как я понял уже считаются неэлегантными, на их место пришел async/await
Вы не поверите, но под сахаром async/await находятся промисы.
Так что статья устарела
Нужно обладать колоссальным опытом что-бы подобное утверждать. На мой взгляд информация в статье актуальна и полезна.
Используйте Коллбэки, как завещали Керниган и Ричи. там по крайней мере понятно когда выполняется код.
Звучит как анти-совет. Промисы действительно решают проблему callback-hell.
Да и зачем вам знать когда выполняется код? — В голову приходит только тики для обновления мира, но обычно это в разработке игр используется.
«callback hell»
callback hell в голове. Не надо использовать анонимные функции.
«Да и зачем вам знать когда выполняется код»
потому что это источник ошибок
Промисы решают не только вложенность (если вы про анонимные функции) — а еще массу полезностей, такие как создание переиспользуемого объекта с окончательным состоянием, большим количеством возможных "продолжений" (then-веток) и инкапсулирование значения. Все это на коллбеках конечно тоже реализовать можно, но… зачем, если это уже есть в промисах?
Прозрачность исполнения у промисов абсолютно такая же, как и у коллбеков. Ни промисы, ни коллбеки не затемняют вопрос "когда же исполнится мой код". Ответ очевиден — eventloop. Синхронные таски — здесь и сейчас, асинхронные — мы не знаем (если мы про результат этих тасков), так как эти веще делегируются на low-level API, который закрыт.
а под промисами прячуться коллбэки
Нет, промисы это новый функционал c новым Api.
потому что это источник ошибок
Приведите пример пожалуйста, не могу придумать сам.
Пример, в котором ошибку сложно/невозможно решить не зная время этой ошибки.
Я, например, использую trackjs в работе, этот сервис позволяет видеть все ошибки на фронте клиента, все до единой.
Нет, промисы это новый функционал c новым Api.
Может, вы даже полифил для них не писали?
Может, вы даже полифил для них не писали?Нет, не писал, но использовал.
Можно узнать причем полифил к промисам?
Промисы — это новый функционал.
Полифилы — следствие graceful degradation подхода и нужны только там где используется этот подход.
В моем случае, например, сборщик сам определяет по целевым браузерам необходим ли полифил, и если необходим включит его сам из core-js.
Можно узнать причем полифил к промисам?
При том, промисы не содержат принципиальной новизны. Иначе бы полифил для них было написать невозможно.
При том, промисы не содержат принципиальной новизныНе содержать принципиальной новизны? — Это классы не содержат принципиальной новизны и являются по факту сахаром, а промисы этот как раз новый функционал, которого никогда не было с новым низкоуровневым Api.
Промисы — это больше про асинхронное программирование и насколько мне известно, до 2014 года в стандарте его не было.
Иначе бы полифил для них было написать невозможно.
Разверните пожалуйста ответ — почему невозможно?
Зная язык программирования и алгоритм можно написать программу, которая повторяет низкоуровневый функционал данного языка программирования, правда у вас будут колоссальные потери в скорости и «ньюансы» работы.
Например, полифил промисов работает в 20 раз медленней чем родной.
Это классы не содержат принципиальной новизны
Для того, чтобы можно было реализовать классы, пришлось переделать процедуру создания объект, а кроме того, добавить возможность pзадать прототип не только создаваемого объекта, но и его конструктора.
Принципиальная новизна заключается в том, что классы позволяют создавать полностью работоспособных наследников от встроенных конструкторов. Например Array.
Полифил этого функционала невозможен.
Разверните пожалуйста ответ — почему невозможно?
А Вы ответ читать не пробовали? Для промисов возможно написать полностью работоспособный полифил. Следовательно, принципиальной новизны они не содержат. Это всего лишь перенос в стандартную библиотеку логики, которая могла бы быть реализована средствами самого языка.
Зная язык программирования и алгоритм можно написать программу, которая повторяет низкоуровневый функционал данного языка программирования, правда у вас будут колоссальные потери в скорости и «ньюансы» работы.
Ну, попробуйте создать наследника Array, так, чтобы Object.getPrototypeOf(MyArray) было равно Array.
Не совсем так, это не заслуга классов самих по себе. Это делается внутренним механизмом через species.
https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Global_Objects/Array/@@species
Для того, чтобы можно было реализовать классы, пришлось переделать процедуру создания объект, а кроме того, добавить возможность pзадать прототип не только создаваемого объекта, но и его конструктора.Да, я об этом и говорю, что class это сахар.
Принципиальная новизна заключается в том, что классы позволяют создавать полностью работоспособных наследников от встроенных конструкторов. Например Array.Это не классы позволяют делать, а обновленный конструктор и новые методы в Object.
Полифил этого функционала невозможен.Простите, но зачем полифил для конструктора Array, в каком-то браузере не работает [] или new Array? Я понимаю к чему вы ведете, но все таки… ощущение что вы хотите завалить меня нюансами языка а не найти в споре истину :)
А Вы ответ читать не пробовали? Для промисов возможно написать полностью работоспособный полифил. Следовательно, принципиальной новизны они не содержат. Это всего лишь перенос в стандартную библиотеку логики, которая могла бы быть реализована средствами самого языка.Да, я прочитал, под развернуть я имел в виду пример.
Новизна != Возможность написания полифила.
Другими словами, возможно или нет реализовать полифил для нового функционала зависит от кол-ва нового функционала и его связью с другим новым/старым функционалом.
Например, для промисов нужен псевдо рантайм и генератор функций, поэтому полифил есть, но очень медленный.
Ну, попробуйте создать наследника Array, так, чтобы Object.getPrototypeOf(MyArray) было равно Array.Мне кажется, что получится (чтобы они вернули true), но боюсь что-то точно перестанет работать либо статичные методы либо нативный конструктор либо еще что-то, они у вас не возвращают true только потому что у функции полифила и нативной функции конструктора разные id в рантайме.
но зачем полифил для конструктора Array, в каком-то браузере не работает [] или new Array?
Вы снова не читаете то, что я пишу. Полифил, позволяющий Вам отнаследоваться от Array, так чтобы это работало.
Новизна != Возможность написания полифила.
А утверждение-то было другое.
Новизна == Невозможность написание полифила.
для промисов нужен псевдо рантайм и генератор функций,
Неправда там тривиальный конструктор, оборачивающий переданную функцию. И тормозить там, по большому счёту, нечему.
chooseToppings(function(toppings){
placeOrder(toppings, function(order){
collectOrder(order, function(pizza){
eatPizza(pizza)
}, failureCallback)
}, failureCallback)
}, failureCallback)
«чуть-чуть» отличается от chooseToppings()
.then(function(toppings){
return placeOrder(toppings)
})
.then(function(order){
return collectOrder(order)
})
.then(function(pizza){
eatPizza(pizza)
})
.catch(failureCallback)
. В том смысле, что в первом случае мы можем по-разному реагировать на каждом уровне, а во втором случае обработчик один. Конечно, в него можно передавать тип исключения, но и данные для обработки всех вариантов исключений придется передавать все… Короче не хватает примера.chooseToppings(gotToppings, failureCallback)
function gotToppings(toppings) {
placeOrder(toppings, gotOrder, failureCallback) }
function gotOrder(order) {
collectOrder(order, gotCollectedOrder, failureCallback) }
function gotCollectedOrder(pizza) {
eatPizza(pizza, failureCallback) }
function failureCallback() {console.log('Не шмогла...')}
Тоже достаточно легко оборачивается. Вы потроха функции jQuery.when видели?
А сколько потом приходится доплачивать программистам, чтобы они с поддержки подобного чуда не убежали через неделю?
"Обещания", "функции обратного вызова", "нам не нужна многослойность" — это ж всё приходится в голове сначала на английский переводить, чтобы понять, что вы имели в виду.
Тогда уж надо было идти до конца, и добавить методы обещаний "тогда", "лови" и "наконец-то".
"Обещания", "функции обратного вызова", "нам не нужна многослойность" — это ж всё приходится в голове сначала на английский переводить
Вы так говорите, как будто это трудно.
Тогда уж надо было идти до конца, и добавить методы обещаний "тогда", "лови" и "наконец-то".
Плохая аналогия — как котёнок с дверцей.
Элегантное асинхронное программирование с помощью промисов