Pull to refresh
5
0
Бадальянц Юрий@LMnet

Software Engineer

Send message

Отличие в том, что сам по себе синтаксис и конструкции языка не форсируют такой подход. Да, приведенный пример показывает, что можно явно разделить асинхронный и синхронный код и всё будет хорошо. Но это не значит что нельзя не разделять асинхронный и синхронный код. Получается страховка от ошибок на уровне договоренностей, а не на уровне конструкций языка. И именно в этом проблема.

Все асинхронные функции явно вынесены внутрь for блока. В случае с async/await синхронные и асинхронные функции перемешаны на одном уровне.

В Scala (и scala.js) существуют и промисы (только используется другой нейминг, вместо Promise они называются Future) и async/await. И все предпочитают использовать именно промисы (фьючи). Причина в том, что async/await создает ложную иллюзию синхронности происходящего. Это может привести к тому, что синхронная и асинхронная логика будут смешаны вместе и в какой-то момент await потеряется перед асинхронной функцией. Или наоборот, await "на всякий случай" будет приписываться везде, даже если функция не асинхронная. При использовании промисов синхронные и асинхронные потоки явно отделены друг от друга. Глазами сразу видно, где тут у нас асинхронное выполнение, а где синхронное. И это потенциально более безопасно и не приведет к ошибкам, которые я выше описал.
Чтобы асинхронный код не превращался в кашу в Scala используется for-comprehension. И такой асинхронный код выглядит почти как синхронный, но при этом явно видно, где тут синхронные части, а где асинхронные.
В Scala/Scala.js коде пример выше выглядел бы примерно следующим образом:


def handleRequestArrows(user: User, sender: ResultSender): Future[SendingResult] {
    val res = for {
        _ <- isUserValidAsync(user)
        (data, rate) <- Future.sequence(Seq(getUserDataAsync(user), getRateAsync("service")))
        savedData <- updateUserDataAsync(user, updateData(data, rate))
        sendingResult <- sender.send(savedData)
    } yield sendingResult
    res.andThen { // обычно это делают на уровне выше, но я добавил сюда, чтобы не отступать от примера
        case Failure(e) => logger.log("An error ocurred", e)
    }
}

Код вполне наглядный. Видно, что за чем идет. Если какой-то шаг вернет ошибку, то выполнение всего блока for-comprehension прервется.

В старой опере на жесты мышью можно было наложить намного больше действий. В Vivaldi количество доступных действий сильно ограничено. Например, я по движению влево/вправо перехожу на соседнюю (левую/правую) открытую вкладки. В текущей версии Vivaldi я не нашел такого действия для жестов. Есть ли это в новой версии? Планируется ли расширить набор действий для жестов?
Такая проблема встречается не только у вас. В комментах в блоге подсказывают, что если сменить встроенную JVM на стороннюю, то рендеринг шрифтов будет аналогичен 15 версии.
Хотелось бы услышать какой-то комментарий от представителей JetBrains по этому поводу. В блоге мне так и не ответили.
Я не говорил, что все нововведения в новых версиях JS — это сахар. Я сказал, что большинство — это синтаксический сахар. То есть это конструкции, которые можно выразить и в ES5, и в ES6. Яркий пример сахара — лямбды. Но, к примеру, символы — это не сахар, потому что в ES5 их не выразишь имеющимися средствами языка.
Обычное использование JS, и использование JS как compilation target — это совершенно разные вещи. Какая разница для компилятора, скомпилировать колбэк в обычную функцию, или в лямбду? Если бы лямбды работали быстрее, смысл был бы. Но на текущий момент ES6 работает медленнее, и у него худшая поддержка браузерами. Именно эту мысль я хотел донести.
Ребята, которые разрабатывают Scala.js экспериментировали с компиляцией в ES6. На текущий момент эти эксперименты показали, что скомпилированный в ES5 код работает быстрее. Для Kotlin, скорее всего, ситуация будет аналогична. К тому же, если использовать JavaScript как compilation target, то особого смысла в ES6/ES7 нет, там большинство нововведений — синтаксический сахар.
Если коротко, в Selenide каждый метод умеет немножко подождать, если надо. Люди называют это «умными ожиданиями».

Правильно я понимаю, что это должно полностью избавить от проблем со stale element reference exception? И каким образом реализовано это умное ожидание?
Так в Scala есть такой функционал. В статье про него мельком сказано. Можно писать так:
private[my.package] val a = 5
И все, что внутри пакета my.package, будет видеть это приватное свойство. В том числе и вложенные пакеты, типа my.package.inside.
2

Information

Rating
Does not participate
Location
Новосибирск, Новосибирская обл., Россия
Date of birth
Registered
Activity