Какая ваша функция здесь
Перейти к содержимому

Какая ваша функция здесь

  • автор:

Функции

Зачастую нам надо повторять одно и то же действие во многих частях программы.

Например, необходимо красиво вывести сообщение при приветствии посетителя, при выходе посетителя с сайта, ещё где-нибудь.

Чтобы не повторять один и тот же код во многих местах, придуманы функции. Функции являются основными «строительными блоками» программы.

Примеры встроенных функций вы уже видели – это alert(message) , prompt(message, default) и confirm(question) . Но можно создавать и свои.

Объявление функции

Для создания функций мы можем использовать объявление функции.

Пример объявления функции:

function showMessage()

Вначале идёт ключевое слово function , после него имя функции, затем список параметров в круглых скобках через запятую (в вышеприведённом примере он пустой) и, наконец, код функции, также называемый «телом функции», внутри фигурных скобок.

function имя(параметры)

Наша новая функция может быть вызвана по своему имени: showMessage() .

function showMessage() < alert( 'Всем привет!' ); >showMessage(); showMessage();

Вызов showMessage() выполняет код функции. Здесь мы увидим сообщение дважды.

Этот пример явно демонстрирует одно из главных предназначений функций: избавление от дублирования кода.

Если понадобится поменять сообщение или способ его вывода – достаточно изменить его в одном месте: в функции, которая его выводит.

Локальные переменные

Переменные, объявленные внутри функции, видны только внутри этой функции.

function showMessage() < let message = "Привет, я JavaScript!"; // локальная переменная alert( message ); >showMessage(); // Привет, я JavaScript! alert( message ); // 

Внешние переменные

У функции есть доступ к внешним переменным, например:

let userName = 'Вася'; function showMessage() < let message = 'Привет, ' + userName; alert(message); >showMessage(); // Привет, Вася

Функция обладает полным доступом к внешним переменным и может изменять их значение.

let userName = 'Вася'; function showMessage() < userName = "Петя"; // (1) изменяем значение внешней переменной let message = 'Привет, ' + userName; alert(message); >alert( userName ); // Вася перед вызовом функции showMessage(); alert( userName ); // Петя, значение внешней переменной было изменено функцией

Внешняя переменная используется, только если внутри функции нет такой локальной.

Если одноимённая переменная объявляется внутри функции, тогда она перекрывает внешнюю. Например, в коде ниже функция использует локальную переменную userName . Внешняя будет проигнорирована:

let userName = 'Вася'; function showMessage() < let userName = "Петя"; // объявляем локальную переменную let message = 'Привет, ' + userName; // Петя alert(message); >// функция создаст и будет использовать свою собственную локальную переменную userName showMessage(); alert( userName ); // Вася, не изменилась, функция не трогала внешнюю переменную

Глобальные переменные

Переменные, объявленные снаружи всех функций, такие как внешняя переменная userName в вышеприведённом коде – называются глобальными.

Глобальные переменные видимы для любой функции (если только их не перекрывают одноимённые локальные переменные).

Желательно сводить использование глобальных переменных к минимуму. В современном коде обычно мало или совсем нет глобальных переменных. Хотя они иногда полезны для хранения важнейших «общепроектовых» данных.

Параметры

Мы можем передать внутрь функции любую информацию, используя параметры.

В нижеприведённом примере функции передаются два параметра: from и text .

function showMessage(from, text) < // параметры: from, text alert(from + ': ' + text); >showMessage('Аня', 'Привет!'); // Аня: Привет! (*) showMessage('Аня', "Как дела?"); // Аня: Как дела? (**)

Когда функция вызывается в строках (*) и (**) , переданные значения копируются в локальные переменные from и text . Затем они используются в теле функции.

Вот ещё один пример: у нас есть переменная from , и мы передаём её функции. Обратите внимание: функция изменяет значение from , но это изменение не видно снаружи. Функция всегда получает только копию значения:

function showMessage(from, text) < from = '*' + from + '*'; // немного украсим "from" alert( from + ': ' + text ); >let from = "Аня"; showMessage(from, "Привет"); // *Аня*: Привет // значение "from" осталось прежним, функция изменила значение локальной переменной alert( from ); // Аня

Значение, передаваемое в качестве параметра функции, также называется аргументом.

  • Параметр – это переменная, указанная в круглых скобках в объявлении функции.
  • Аргумент – это значение, которое передаётся функции при её вызове.

Мы объявляем функции со списком параметров, затем вызываем их, передавая аргументы.

Рассматривая приведённый выше пример, мы могли бы сказать: "функция showMessage объявляется с двумя параметрами, затем вызывается с двумя аргументами: from и "Привет" ".

Значения по умолчанию

Если при вызове функции аргумент не был указан, то его значением становится undefined .

Например, вышеупомянутая функция showMessage(from, text) может быть вызвана с одним аргументом:

showMessage("Аня");

Это не приведёт к ошибке. Такой вызов выведет "*Аня*: undefined" . В вызове не указан параметр text , поэтому предполагается, что text === undefined .

Если мы хотим задать параметру text значение по умолчанию, мы должны указать его после = :

function showMessage(from, text = "текст не добавлен") < alert( from + ": " + text ); >showMessage("Аня"); // Аня: текст не добавлен

Теперь, если параметр text не указан, его значением будет "текст не добавлен"

В данном случае "текст не добавлен" это строка, но на её месте могло бы быть и более сложное выражение, которое бы вычислялось и присваивалось при отсутствии параметра. Например:

function showMessage(from, text = anotherFunction()) < // anotherFunction() выполнится только если не передан text // результатом будет значение text >

Вычисление параметров по умолчанию

В JavaScript параметры по умолчанию вычисляются каждый раз, когда функция вызывается без соответствующего параметра.

В приведённом выше примере, функция anotherFunction() не будет вызвана вообще, если указан параметр text .

С другой стороны, функция будет независимо вызываться каждый раз, когда text отсутствует.

Использование параметров по умолчанию в ранних версиях JavaScript

Ранние версии JavaScript не поддерживали параметры по умолчанию. Поэтому существуют альтернативные способы, которые могут встречаться в старых скриптах.

Например, явная проверка на undefined :

function showMessage(from, text) < if (text === undefined) < text = 'текст не добавлен'; >alert( from + ": " + text ); >

…Или с помощью оператора || :

function showMessage(from, text) < // Если значение text ложно, тогда присвоить параметру text значение по умолчанию // заметим, что при этом пустая строка text === "" будет также считаться отсутствующим значением text = text || 'текст не добавлен'; . >

Альтернативные параметры по умолчанию

Иногда имеет смысл присваивать значения по умолчанию для параметров не в объявлении функции, а на более позднем этапе.

Во время выполнения функции мы можем проверить, передан ли параметр, сравнив его с undefined :

function showMessage(text) < // . if (text === undefined) < // если параметр отсутствует text = 'пустое сообщение'; >alert(text); > showMessage(); // пустое сообщение

…Или мы можем использовать оператор || :

function showMessage(text) < // если значение text ложно или равняется undefined, тогда присвоить text значение 'пусто' text = text || 'пусто'; . >

Современные движки JavaScript поддерживают оператор нулевого слияния ?? . Его использование будет лучшей практикой, в случае, если большинство ложных значений, таких как 0 , следует расценивать как «нормальные».

function showCount(count) < // если count равен undefined или null, показать "неизвестно" alert(count ?? "неизвестно"); >showCount(0); // 0 showCount(null); // неизвестно showCount(); // неизвестно

Возврат значения

Функция может вернуть результат, который будет передан в вызвавший её код.

Простейшим примером может служить функция сложения двух чисел:

function sum(a, b) < return a + b; >let result = sum(1, 2); alert( result ); // 3

Директива return может находиться в любом месте тела функции. Как только выполнение доходит до этого места, функция останавливается, и значение возвращается в вызвавший её код (присваивается переменной result выше).

Вызовов return может быть несколько, например:

function checkAge(age) < if (age >= 18) < return true; >else < return confirm('А родители разрешили?'); >> let age = prompt('Сколько вам лет?', 18); if ( checkAge(age) ) < alert( 'Доступ получен' ); >else

Возможно использовать return и без значения. Это приведёт к немедленному выходу из функции.

function showMovie(age) < if ( !checkAge(age) ) < return; >alert( "Вам показывается кино" ); // (*) // . >

В коде выше, если checkAge(age) вернёт false , showMovie не выполнит alert .

Результат функции с пустым return или без него – undefined

Если функция не возвращает значения, это всё равно, как если бы она возвращала undefined :

function doNothing() < /* пусто */ >alert( doNothing() === undefined ); // true

Пустой return аналогичен return undefined :

function doNothing() < return; >alert( doNothing() === undefined ); // true

Никогда не добавляйте перевод строки между return и его значением

Для длинного выражения в return может быть заманчиво разместить его на нескольких отдельных строках, например так:

return (some + long + expression + or + whatever * f(a) + f(b))

Код не выполнится, потому что интерпретатор JavaScript подставит точку с запятой после return . Для него это будет выглядеть так:

return; (some + long + expression + or + whatever * f(a) + f(b))

Таким образом, это фактически стало пустым return .

Если мы хотим, чтобы возвращаемое выражение занимало несколько строк, нужно начать его на той же строке, что и return . Или, хотя бы, поставить там открывающую скобку, вот так:

return ( some + long + expression + or + whatever * f(a) + f(b) )

И тогда всё сработает, как задумано.

Выбор имени функции

Функция – это действие. Поэтому имя функции обычно является глаголом. Оно должно быть кратким, точным и описывать действие функции, чтобы программист, который будет читать код, получил верное представление о том, что делает функция.

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

Например, функции, начинающиеся с "show" обычно что-то показывают.

Функции, начинающиеся с…

  • "get…" – возвращают значение,
  • "calc…" – что-то вычисляют,
  • "create…" – что-то создают,
  • "check…" – что-то проверяют и возвращают логическое значение, и т.д.

Примеры таких имён:

showMessage(..) // показывает сообщение getAge(..) // возвращает возраст (получая его каким-то образом) calcSum(..) // вычисляет сумму и возвращает результат createForm(..) // создаёт форму (и обычно возвращает её) checkPermission(..) // проверяет доступ, возвращая true/false

Благодаря префиксам, при первом взгляде на имя функции становится понятным, что делает её код, и какое значение она может возвращать.

Одна функция – одно действие

Функция должна делать только то, что явно подразумевается её названием. И это должно быть одним действием.

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

Несколько примеров, которые нарушают это правило:

  • getAge – будет плохим выбором, если функция будет выводить alert с возрастом (должна только возвращать его).
  • createForm – будет плохим выбором, если функция будет изменять документ, добавляя форму в него (должна только создавать форму и возвращать её).
  • checkPermission – будет плохим выбором, если функция будет отображать сообщение с текстом доступ разрешён/запрещён (должна только выполнять проверку и возвращать её результат).

В этих примерах использовались общепринятые смыслы префиксов. Конечно, вы в команде можете договориться о других значениях, но обычно они мало отличаются от общепринятых. В любом случае вы и ваша команда должны чётко понимать, что значит префикс, что функция с ним может делать, а чего не может.

Сверхкороткие имена функций

Имена функций, которые используются очень часто, иногда делают сверхкороткими.

Например, фреймворк jQuery определяет функцию с помощью $ . В библиотеке Lodash основная функция представлена именем _ .

Это исключения. В основном имена функций должны быть в меру краткими и описательными.

Функции == Комментарии

Функции должны быть короткими и делать только что-то одно. Если это что-то большое, имеет смысл разбить функцию на несколько меньших. Иногда следовать этому правилу непросто, но это определённо хорошее правило.

Небольшие функции не только облегчают тестирование и отладку – само существование таких функций выполняет роль хороших комментариев!

Например, сравним ниже две функции showPrimes(n) . Каждая из них выводит простое число до n .

Первый вариант использует метку nextPrime :

function showPrimes(n) < nextPrime: for (let i = 2; i < n; i++) < for (let j = 2; j < i; j++) < if (i % j == 0) continue nextPrime; >alert( i ); // простое > >

Второй вариант использует дополнительную функцию isPrime(n) для проверки на простое:

function showPrimes(n) < for (let i = 2; i < n; i++) < if (!isPrime(i)) continue; alert(i); // простое >> function isPrime(n) < for (let i = 2; i < n; i++) < if ( n % i == 0) return false; >return true; >

Второй вариант легче для понимания, не правда ли? Вместо куска кода мы видим название действия ( isPrime ). Иногда разработчики называют такой код самодокументируемым.

Таким образом, допустимо создавать функции, даже если мы не планируем повторно использовать их. Такие функции структурируют код и делают его более понятным.

Итого

Объявление функции имеет вид:

function имя(параметры, через, запятую) < /* тело, код функции */ >
  • Передаваемые значения копируются в параметры функции и становятся локальными переменными.
  • Функции имеют доступ к внешним переменным. Но это работает только изнутри наружу. Код вне функции не имеет доступа к её локальным переменным.
  • Функция может возвращать значение. Если этого не происходит, тогда результат равен undefined .

Для того, чтобы сделать код более чистым и понятным, рекомендуется использовать локальные переменные и параметры функций, не пользоваться внешними переменными.

Функция, которая получает параметры, работает с ними и затем возвращает результат, гораздо понятнее функции, вызываемой без параметров, но изменяющей внешние переменные, что чревато побочными эффектами.

  • Имя функции должно понятно и чётко отражать, что она делает. Увидев её вызов в коде, вы должны тут же понимать, что она делает, и что возвращает.
  • Функция – это действие, поэтому её имя обычно является глаголом.
  • Есть много общепринятых префиксов, таких как: create… , show… , get… , check… и т.д. Пользуйтесь ими как подсказками, поясняющими, что делает функция.

Функции являются основными строительными блоками скриптов. Мы рассмотрели лишь основы функций в JavaScript, но уже сейчас можем создавать и использовать их. Это только начало пути. Мы будем неоднократно возвращаться к функциям и изучать их всё более и более глубоко.

Задачи

Обязателен ли "else"?

важность: 4

Следующая функция возвращает true , если параметр age больше 18 .

В ином случае она запрашивает подтверждение через confirm и возвращает его результат:

function checkAge(age) < if (age >18) < return true; >else < // . return confirm('Родители разрешили?'); >>

Будет ли эта функция работать как-то иначе, если убрать else ?

function checkAge(age) < if (age >18) < return true; >// . return confirm('Родители разрешили?'); >

Есть ли хоть одно отличие в поведении этого варианта?

Оба варианта функций работают одинаково, отличий нет.

Перепишите функцию, используя оператор '?' или '||'

важность: 4

Следующая функция возвращает true , если параметр age больше 18 .

В ином случае она задаёт вопрос confirm и возвращает его результат.

function checkAge(age) < if (age >18) < return true; >else < return confirm('Родители разрешили?'); >>

Перепишите функцию, чтобы она делала то же самое, но без if , в одну строку.

Сделайте два варианта функции checkAge :

  1. Используя оператор ?
  2. Используя оператор ||
function checkAge(age) < return (age >18) ? true : confirm('Родители разрешили?'); >

Используя оператор || (самый короткий вариант):

function checkAge(age) < return (age >18) || confirm('Родители разрешили?'); >

Обратите внимание, что круглые скобки вокруг age > 18 не обязательны. Они здесь для лучшей читаемости кода.

Об X Premium

X Premium — это добровольная платная подписка, которая добавляет в учетную запись синюю галочку и дает ранний доступ к избранным новым функциям, например к функции редактирования постов. Оформите подписку прямо сейчас по цене от 8 долл. США в месяц или 84 долл. США в год (эквивалент в местной валюте) в одной из стран, где доступна эта возможность, чтобы получить синюю галочку и ранний доступ к функциям.*

Нажмите здесь, чтобы получить информацию о ценах.

Все функции X Premium, кроме синей галочки, становятся доступны сразу. Галочка появляется в профиле подписчика после проверки соответствия его учетной записи требованиям.

Мы также запустили новый сервис «Подлинные организации», который предназначен для предприятий, государственных органов и некоммерческих организаций на платформе X, который предлагает золотую галочку, значки связанных профилей, поддержку премиум-класса, защиту от имитации и другие функции для организаций. Подробнее о сервисе «Подлинные организации» можно узнать здесь.

Функции

Помимо синей галочки, X Premium предлагает функции, которые повышают удобство, позволяя подписчикам настраивать интерфейс. Подписчики получают доступ к мощным инструментам управления, предназначенным для персонализации X, а также к новейшим функциям, еще не доступным остальным пользователям. Отправьте ваши отзывы @Premium.

Premium включает ряд функций*, повышающих удобство, в том числе:

  • Редактирование постов. Очень востребованная функция, которая дает возможность несколько раз изменить исходный пост в течение 1 часа после его публикации. Ее можно использовать для того, чтобы обновить текст, отметить кого-нибудь или изменить порядок прикрепленных медиафайлов. В настоящее время редактировать можно только исходные посты и цитаты.
  • В два раза меньше рекламы. Вы будете видеть на 50 % меньше рекламы в лентах «Вы читаете» и «Для вас». При прокручивании вы будете видеть примерно в два раза больше органических и непродвигаемых постов между продвигаемыми постами или рекламой. Иногда между продвигаемыми постами будет отображаться больше или меньше непродвигаемых постов. Функция «В два раза меньше рекламы» неприменима к продвигаемому контенту в других частях X, включая, помимо прочего, рекламу в профилях и ответах на посты, продвигаемые мероприятия в обзорах, продвигаемые тренды и продвигаемые учетные записи, на которые рекомендуется подписаться. Подписчики Premium получат доступ к этой функции после проверки их учетной записи на соответствие требованиям и добавления к ней синей галочки.
  • Приоритетная позиция в переписках и результатах поиска. Рейтинг постов, с которыми вы взаимодействуете, будет немного подниматься. Кроме того, ваши ответы будут размещаться ближе к началу ветки. Сведения об ответах, упоминаниях и взаимодействиях подписчиков Premium будут появляться на вкладке «Подлинные», которую другие пользователи видят на вкладке уведомлений.
  • Более длинные посты. Хотите публиковать посты длиной более 280 символов? С помощью этой функции подписчики могут писать посты, содержащие до 25 000 символов. Это также касается постов с цитатами и ответов. Стандартные функции, такие как публикация медиафайлов, создание опросов и использование хештегов, остаются доступными. Читать длинные посты могут все, а создавать их — только подписчики Premium.
  • Форматирование текста. Теперь вы можете использовать в своих постах на сайте x.com жирный шрифт и курсив.
  • Избранные посты. Выставляйте свои лучшие посты напоказ, добавив их на вкладку «Избранное» в вашем профиле.
  • Папки закладок. Эта функция позволяет подписчикам упорядочивать сохраненные посты по папкам, чтобы легко находить их впоследствии. Premium позволяет создавать неограниченное число закладок и папок закладок, причем они всегда будут оставаться приватными.
  • Индивидуальные значки приложения. Эта функция позволяет выбрать, как будет выглядеть значок приложения X на вашем телефоне. Мы предусмотрели несколько разноцветных вариантов на ваш выбор. Регулярно проверяйте настройки, чтобы не пропустить новые варианты, доступные в течение ограниченного времени.
  • Индивидуальное меню навигации. Эта функция позволяет выбрать, что должно отображаться на панели навигации, чтобы иметь быстрый доступ к наиболее важным для вас контенту и разделам X. Вы можете выбрать от 2 до 6 элементов, которые будут располагаться на панели навигации внизу страницы. Если вы передумаете, то сможете в любой момент вернуть стандартный вид панели.
  • Популярные статьи. Это быстрый доступ к статьям, которыми чаще всего делятся в вашей сети. Эта функция автоматически выводит списки статей, которыми чаще всего делятся люди, которых вы читаете, а также те, кого читают они, чтобы вы могли легко найти тот тип контента, который вас интересует.
  • Режим чтения. Эта функция преобразует длинные ветки в более приятный и удобный для чтения формат. Мы создали режим чтения для того, чтобы вы могли читать ветки без лишнего шума. Чтобы включить эту функцию, нажмите значок «Режим чтения» в верхней части ветки. С помощью этого значка также можно изменить размер шрифта.
  • Отмена постов. Эта функция позволяет отозвать пост после отправки, но только до того, как он станет виден другим пользователям X. Это не кнопка редактирования*, а скорее возможность предварительно оценить и при необходимости изменить пост, прежде чем его увидят все. По окончании периода отмены пост становится виден вашим читателям, и вы можете оставить его или удалить как обычно в X.
  • Загрузка более длинных видео. Эта функция позволяет делиться с подписчиками контентом большего объема. Подписчики Premium могут загружать на сервер видео продолжительностью до ~3 часов и объемом до 8 ГБ (1080p) (только на сайте x.com и в приложении X для iOS). Более подробная информация доступна здесь.
  • Темы оформления. Эта функция Premium позволяет выбрать для приложения одну из разноцветных тем оформления.
  • Изображения профиля NFT. Мы добавляем NFT в настройки профиля, чтобы вы могли показать NFT, которыми вы владеете, на шестигранной фотографии профиля в своей учетной записи. После временного подключения к вашему криптокошельку, позволяющему установить NFT в качестве изображения вашего профиля, ваш цифровой актив отображается в виде специального шестиугольника, который идентифицирует вас как владельца этого NFT.
  • Двухфакторная аутентификация по SMS. Благодаря этому способу двухфакторной аутентификации подписчики могут добавить в свою учетную запись дополнительный уровень защиты. Учтите, что доступность этой функции в рамках Premium зависит от страны и оператора мобильной связи.
  • Скрытие галочки. Как подписчик, вы можете скрыть галочку в своей учетной записи. Галочка будет скрыта в вашем профиле и постах. Галочка все равно может отображаться в некоторых местах, и использование некоторых функций может говорить о том, что у вас есть активная подписка. Некоторые функции могут быть недоступны, пока ваша галочка скрыта. Мы продолжим совершенствовать эту функцию.
  • Создание сообщества. Как подписчик Premium, вы можете создать сообщество, в котором другие пользователи смогут знакомиться, общаться и обсуждать интересующие вас темы.
  • Доступ к Media Studio. Управление изображениями и видео, загруженными на сервер X с помощью studio.x.com. Узнайте больше о Media Studio.
  • Доступ к X Pro. Просматривайте сразу несколько настраиваемых лент, обновляющихся в реальном времени, используйте расширенный поиск, добавляйте в свою учетную запись соавторов и администраторов — все это и многое другое можно делать в X Pro. Узнайте больше об X Pro.

Узнайте о том, как пользоваться функциями Premium, здесь.

*Доступность функций зависит от платформы и местоположения. По мере развития и улучшения сервиса Premium его функции могут периодически меняться.

Доступность

Оформить подписку Premium можно из любой страны на веб-сайте или в приложении для iOS или Android. Доступность функций зависит от платформы. В будущем мы также можем по своему усмотрению и без уведомления вводить для новых учетных записей периоды ожидания.

X имеет право на свое усмотрение, без предупреждения и без предоставления компенсации удалить вашу синюю галочку, например в случае нарушения вами Условий предоставления услуг или приостановки действия вашей учетной записи.

Требования

Мы стремимся обеспечивать добросовестное использование X и хотим, чтобы люди могли безопасно взаимодействовать друг с другом на нашей платформе. В рамках регистрации все подписчики должны подтвердить свой номер телефона. После оформления подписки любые изменения, касающиеся фотографии профиля, отображаемого имени или имени пользователя (@псевдонима), приводят к потере синей галочки до тех пор, пока мы не убедимся, что учетная запись по-прежнему соответствует нашим требованиям. Вносить дополнительные изменения в период проверки нельзя. Подробнее об условиях получения синей галочки можно узнать здесь.

Текущие подписчики

Пользователи, оформившие подписку за 7,99 долл. США на платформе iOS, получат уведомление от Apple о том, что их подписка будет автоматически продлена по цене 11 долл. США в месяц или 114,99 долл. США в год (или эквивалент в местной валюте), если они ее не отменят.

Те, кто изначально оформил подписку в iOS за 2,99 или 4,99 долл. США в месяц, должны будут переоформить ее за 8 долл. США в месяц или 84 долл. США в год на сайте Twitter либо за 11 долл. США в месяц или 114,99 долл. США в год (или эквивалент в местной валюте) в приложении для iOS, если они не хотят ее потерять.

Текущим подписчикам следует управлять подпиской на той платформе, где она была оформлена, чтобы она сохранилась до окончания текущего расчетного периода. В противном случае она будет отменена после отправки предупреждения.

*Примечание. Пользователи, которые не переоформят подписку и не отменят ее автоматическое продление, будут иметь доступ к функциям до конца текущего расчетного периода.

Часто задаваемые вопросы

Что такое X Premium?

X Premium — это добровольная подписка с ежемесячной оплатой, которая добавляет в учетную запись синюю галочку и дает ранний доступ к избранным новым функциям, например к функции редактирования постов.

Где можно приобрести подписку X Premium?

В настоящее время X Premium можно приобрести на сайте за 8 долл. США в месяц или 84 долл. США в год, а в приложении для iOS или Android – за 11 долл. США в месяц или 114,99 долл. США в год (или эквивалент в местной валюте). Оформить подписку X Premium можно из любой страны на веб-сайте или в приложении для iOS или Android.

Примечание. Кроме того, такая возможность может быть недоступна пользователям X, которые не выполняли никаких действий в течение последних 30 дней либо изменили фотографию профиля, отображаемое имя или имя пользователя (@псевдоним) в течение последних 3 дней. Для оформления подписки необходим подтвержденный номер телефона. Мы работаем над усовершенствованной процедурой для новых учетных записей X, чтобы свести к минимуму риск того, что кто-то будет выдавать себя за другое лицо, поэтому можем без уведомления вводить периоды ожидания для новых пользователей.

Где регистрируется подписка?

Чтобы оформить подписку на сайте, нажмите здесь или откройте x.com и выберите Подлинные в боковом меню навигации. Если вы еще не подтвердили свой номер телефона, вам нужно будет это сделать. В конце подтвердите оплату подписки.

Чтобы оформить подписку в приложении для iOS или Android, откройте меню профиля и выберите «Подлинные». Если вы еще не подтвердили свой номер телефона, вам нужно будет это сделать. Чтобы завершить оформление подписки, следуйте инструкциям в приложении.

Сколько стоит подписка на новую версию Premium?

Подписка Premium оплачивается ежемесячно или ежегодно и может быть оформлена на сайте либо в приложении для iOS или Android. Стоимость подписки указывается в местной валюте тех стран, где она доступна, и составляет от 8 долл. США в месяц или 84 долл. США в год. Если Premium можно приобрести в вашем регионе, стоимость в местной валюте будет отображаться на сайте и в приложении для iOS или Android. Подробнее о тарифных планах и их стоимости в странах, где доступна подписка, можно узнать здесь.

Предусмотрен ли возврат средств за подписку Premium?

Если иное не требуется по закону, средства за подписку не возвращаются. Это относится, среди прочего, к подпискам в учетных записях X, действие которых было приостановлено или к которым по какой-либо причине был утрачен доступ, а также к ситуациям, когда некоторые функции подписки временно или постоянно недоступны.

Примечание. Если у вас возникли трудности, связанные с возвратом средств или отменой подписки в приложении, обратитесь напрямую к Apple или Android.

Какие функции предоставляет подписка Premium?

Активная подписка Premium добавляет в учетную запись синюю галочку и дает ранний доступ к избранным новым функциям. По мере развития и улучшения сервиса Premium его функции могут меняться в любой момент.

Полный список доступных функций можно просмотреть здесь.

Как действует приоритетный рейтинг?

Мы стараемся сначала показывать наиболее интересные на наш взгляд материалы, которые вносят ценный вклад в переписку, то есть релевантный, достоверный и безопасный контент. Пользователи X заметят, что ответы владельцев подлинных учетных записей имеют небольшой приоритет над остальными ответами. В настоящее время мы тестируем разные уровни приоритета контента, который публикуют подписчики Premium, относительно других факторов, которые учитываются в рейтинге переписок.

Что такое NFT и как его использовать в качестве изображения профиля?

NFT (сокращение от Non-Fungible Tokens, «невзаимозаменяемые токены») — это уникальные цифровые объекты, такие как произведения искусства, с подтверждением права собственности, которое хранится в блокчейне (общедоступной цифровой базе данных). После временного подключения к вашему криптокошельку, позволяющему установить NFT в качестве изображения профиля, ваш цифровой актив будет отображаться в виде специального шестиугольника, идентифицирующего вас как владельца этого NFT. В настоящее время X поддерживает только NFT со статическими изображениями (JPEG, PNG), отчеканенные на блокчейне Ethereum (например, токены ERC-721 и ERC-1155). Подробнее о том, как настроить изображение профиля NFT, можно узнать здесь.

Что такое криптокошелек?

Криптокошельки позволяют хранить и совершать операции (покупать, продавать, конвертировать, отправлять и т. д.) с токенами, принадлежащими вашему общедоступному адресу кошелька. К ним относятся NFT, которые являются одним из видов токенов.

Криптокошелек имеет один или несколько публичных адресов, которые иногда называют «счетами». Этот адрес является общедоступным, поэтому любой, кто знает адрес вашего кошелька, сможет увидеть все транзакции и авуары вашего кошелька.

Чтобы установить изображение профиля NFT, вам необходимо подключить свою учетную запись X к криптокошельку, в котором хранится нужный NFT.

В настоящее время X поддерживает такие криптокошельки: Argent, Coinbase Wallet, Ledger Live, MetaMask, Rainbow, Trust Wallet.

Безопасно ли использовать NFT как изображение профиля?

Если вы установите NFT в качестве изображения профиля, другие пользователи смогут ассоциировать вашу учетную запись X с общедоступным адресом подключенного к ней криптокошелька. Это значит, что ваша учетная запись X будет привязана к вашим текущим и прошлым транзакциям и авуарам криптокошелька, включая все остальные NFT в этом кошельке, поскольку эта информация доступна на публичном блокчейне. При подключении криптокошелька к учетной записи X следует помнить о следующем:

X никогда не будет запрашивать средства из вашего криптокошелька. Вам следует сохранять бдительность и проверять все входящие запросы к вашему кошельку. Не принимайте никаких запросов на перевод средств, если это не известная вам операция.

X никогда не будет запрашивать ваш закрытый ключ или сид-фразу, и вам ни в коем случае не следует передавать свои закрытые ключи или сид-фразы куда-либо, в том числе в X.

Мы не будем поддерживать постоянную связь с вашим криптокошельком, однако сохраним его общедоступный адрес, чтобы иметь подтверждение того, что он продолжает хранить NFT, который вы установили в качестве изображения профиля.

Что произойдет, если я продам или передам NFT на картинке моего профиля?

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

Для отображения другого NFT выберите один из NFT в вашем кошельке или привяжите другой кошелек.

Чем старая синяя галочка отличается от синей галочки, предоставляемой в рамках подписки X Premium?

Раньше такой галочкой отмечались активные, значимые и подлинные учетные записи, которые представляли интерес для общественности и прошли независимую проверку подлинности на основе определенных требований.

Теперь синяя галочка означает, что у учетной записи есть действующая подписка X Premium. Учетные записи, получившие синюю галочку в рамках подписки X Premium, не будут проходить проверку для подтверждения того, что они являются активными, значимыми и подлинными, как это было раньше.

Что такое «Подлинные организации» в X?

Подписка «Подлинные организации» предназначена для предприятий, государственных органов и некоммерческих организаций на платформе X, который предлагает золотую галочку, значки связанных профилей, поддержку премиум-класса, защиту от имитации и другие функции для организаций.

Что означает значок принадлежности?

Сервис «Подлинные организации» позволяет компаниям связывать другие учетные записи со своей. Связанные учетные записи получают метку с изображением с картинки профиля этой компании.

Что означает золотой значок? В чем разница между синей и золотой галочкой?

Золотой галочкой обозначаются официальные учетные записи организаций, участвующие в программе «Подлинные организации» в X. Синяя галочка означает, что учетная запись имеет подписку Premium и может представлять физическое лицо или организацию.

Узнайте больше о метках в профилях и их значении.

Чем учетная запись с синей галочкой отличается от учетной записи, обозначенной как официальная?

Помимо синей галочки X также может использовать специальные визуальные обозначения, такие как метки и значки, в профилях учетных записей, чтобы предоставить больше контекста о них и обозначить их типы. Метка «Официально» может быть установлена в профилях правительственных учетных записей (принадлежащих соответствующим учреждениям, служащим на выборных или назначаемых должностях, многопрофильным организациям)*, учетных записей некоторых политических организаций (например, политических партий), коммерческих компаний, в том числе торговых партнеров, крупных брендов, информагентств, издателей и некоторых других общественных деятелей.

*В профилях прогосударственных СМИ и правительственных органов, которые являются каналами связи геополитического или официального государственного значения, отображается специальный значок. Узнайте больше о метках в профилях и их значении.

Входит ли в Premium выделенная поддержка?

Пользователи подписки Premium могут пользоваться специальной поддержкой только по вопросам, связанным с подпиской. Например, мы можем помочь вам с управлением подпиской Premium, доступом к учетной записи Premium или настройкам, а также в случае сложностей с оформлением подписки Premium. Кроме того, мы поможем устранить проблемы с функциями, доступными только подписчикам.

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

Одна из наших целей — обеспечивать лучшую в отрасли поддержку клиентов. Мы стремимся подходить ко всем пользователям с позиций справедливости и равноправия. Правила X остаются неизменными для всех подписчиков.

Могут ли подписчики менять свое отображаемое имя и имя пользователя?

После оформления подписки Premium любые изменения, касающиеся фотографии профиля, отображаемого имени или имени пользователя (@псевдонима), приводят к потере синей галочки до тех пор, пока мы не убедимся, что учетная запись по-прежнему соответствует нашим требованиям. Вносить дополнительные изменения в период проверки нельзя. Подробнее об условиях получения синей галочки можно узнать здесь.

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

Мы стремимся сделать X безопасным местом для всех, кто хотел бы участвовать в общественном диалоге. Поэтому вопросы, связанные с применением мер воздействия, и жалобы от подписчиков будут и дальше рассматриваться нашими специалистами по контролю за соблюдением правил согласно существующей в настоящее время процедуре.

Означает ли это нововведение, что бесплатной версии X больше не будет?

X не перестанет быть бесплатным. X Premium — это просто дополнительная возможность настроить X так, чтобы он стал еще удобнее.

При подписке Premium нет рекламы?

X Premium в настоящее время не предлагает среду без рекламы, но подписчики получают примерно на 50% меньше рекламы в ленте на главной странице.

Почему при подписке Premium есть реклама?

Подписка Premium полностью добровольная, а наши первые функции разработаны специально для конкретного сегмента наших самых вовлеченных пользователей. В конечном итоге наша цель — с помощью премиум-функций предоставить пользователям достаточную ценность, чтобы они ощущали, что подписка стоит своих денег.

Можно ли получить бесплатный пробный период Premium?

К сожалению, на данный момент бесплатный пробный период Premium не предоставляется.

Нужна помощь с вашей подпиской Premium?

Если у вас уже есть подписка X Premium и вы не увидели здесь ответа на свой вопрос, перейдите в Справочный центр X Premium, ознакомьтесь с нашими инструкциями или заполните эту форму. Чтобы следить за обновлениями, начните читать @Premium.

Как приостановить или отменить подписку Premium?

Если вы захотите отменить подписку, вы сможете это сделать в настройках на той платформе, где вы ее приобрели. Функции Premium перестанут быть доступны по окончании вашего платежного цикла.

Во избежание дальнейшего списания средств подписку Premium необходимо отменить не менее чем за 24 часа до ее автоматического возобновления. Отмена подписки не возместит уже оплаченные вами средства.

Примечание. Если вы оформите новую подписку Premium, а затем отмените ее, синяя галочка будет оставаться у вас до завершения оплаченного срока подписки, если только действие вашей учетной записи не будет приостановлено или X не удалит галочку раньше по иной причине.

Для чего X вносит это изменение в Blue и подтверждение подлинности?

Это важный шаг к повышению качества переписок в X. Эти изменения призваны сократить количество поддельных и ненадежных учетных записей, а также повысить качество услуг платформы, чтобы люди могли безопасно присоединяться к нашей платформе и пользоваться ей.

Нужно ли переходить на новую версию месячной подписки Premium, чтобы получить синюю галочку?

Да. Пользователям, которые оформили подписку на сайте, следует перейти на новую версию за 8 долл. США в месяц или 84 долл. США в год (или эквивалент в местной валюте). Пользователям, которые оформили подписку в приложении для iOS или Android, нужно перейти на версию за 11 долл. США в месяц или 114,99 долл. США в год (или эквивалент в местной валюте), чтобы получить доступ к функциям и синюю галочку*.

*Все функции X Premium, кроме синей галочки, становятся доступны сразу. Галочка появляется в профиле подписчика после проверки соответствия его учетной записи требованиям.

Почему моя синяя галочка до сих пор не появилась?

Большинство функций Premium, кроме синей галочки, становятся доступны сразу. Галочка появляется в профиле подписчика после проверки соответствия его учетной записи требованиям.

Могу ли я удалить синюю галочку из своей учетной записи? В связи с чем она может быть удалена?

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

Галочка временно удаляется из учетных записей с подпиской Premium после изменения отображаемого имени, фотографии профиля или имени пользователя (@псевдонима), пока эти изменения не будут проверены.

X имеет право на свое усмотрение, без предупреждения и без предоставления компенсации удалить вашу синюю галочку, например в случае нарушения вами Условий предоставления услуг или приостановки действия вашей учетной записи.

Получу ли я компенсацию за свою ежемесячную подписку на прежнюю версию Blue, оплаченную до ее преобразования в Premium?

Если иное не требуется по закону, средства за подписку Premium не возвращаются. Дополнительные сведения можно найти здесь.

Цены

Страна Цена в iOS (ежемесячно) Цена на сайте (ежемесячно) Цена в Android (ежемесячно) Цена в iOS (ежегодно) Цена на сайте (ежегодно) Цена в Android (ежегодно)
США 11,00 $ 8,00 $ 11,00 $ 114,99 $ 84,00 $ 114,99 $
Великобритания 11,00 £ 9,60 £ 11,00 £ 114,99 £ 100,80 £ 114,99 £
Канада 15,00 $ 10,00 $ 15,00 $ 154,99 $ 105,00 $ 154,99 $
Австралия 19,00 $ 13,00 $ 19,00 $ 194,99 $ 135,00 $ 194,99 $
Новая Зеландия 19,00 $ 13,00 $ 19,00 $ 194,99 $ 135,00 $ 194,99 $
Япония 1380 ¥ 980 ¥ 1380 ¥ 14 300 ¥ 10 280 ¥ 14 300 ¥
Бразилия 60,00 R$ 42 BRL 60,00 R$ 629,00 R$ 440 BRL 629,00 R$
Индонезия 165 000 Rp 120 000 Rp 165 000 Rp 1 719 000 Rp 1 250 000 Rp 1 719 000 Rp
Индия 900,00 ₹ 650,00 ₹ 900,00 ₹ 9400,00 ₹ 6800,00 ₹ 9400,00 ₹
Саудовская Аравия 42,00 SR 30 SAR 42,00 SR 434,99 SR 315 SAR 434,99 SR
Франция 11,00 € 9,60 € 11,00 € 114,99 € 100,80 € 114,99 €
Германия 11,00 € 9,52 € 11,00 € 114,99 € 99,96 € 114,99 €
Испания 11,00 € 9,68 € 11,00 € 114,99 € 101,64 € 114,99 €
Италия 11,00 € 9,76 € 11,00 € 114,99 € 102,48 € 114,99 €
Португалия 11,00 € 9,84 € 11,00 € 114,99 € 103,32 € 114,99 €
Нидерланды 11,00 € 9,68 € 11,00 € 114,99 € 101,64 € 114,99 €
Польша 49,00 zł 44,28 zł 49,00 zł 514,99 zł 461,24 zł 514,99 zł
Ирландия 11,00 € 9,84 € 11,00 € 114,99 € 103,32 € 114,99 €
Бельгия 11,00 € 9,68 € 11,00 € 114,99 € 101,64 € 114,99 €
Швеция 115,00 kr 103,75 kr 115,00 kr 1200,00 kr 1087,50 kr 1200,00 kr
Румыния 51,00 lei 44,03 lei 51,00 lei 529,99 lei 464,10 lei 529,99 lei
Чехия 249,00 Kč 216,59 Kč 249,00 Kč 2550,00 Kč 2262,70 Kč 2550,00 Kč
Финляндия 11,00 € 9,92 € 11,00 € 114,99 € 104,16 € 114,99 €
Дания 77,00 kr. 70,00 kr. 77,00 kr. 800,00 kr. 737,50 kr. 800,00 kr.
Греция 11,00 € 9,92 € 11,00 € 114,99 € 104,16 € 114,99 €
Австрия 11,00 € 9,60 € 11,00 € 114,99 € 100,80 € 114,99 €
Венгрия 4000,00 Ft 3619,50 Ft 4000,00 Ft 41 490 Ft 38 100 Ft 41 490 Ft
Болгария 20,00 lev 18,00 lev 20,00 lev 209,99 lev 185,99 lev 209,99 lev
Литва 11,00 € 9,68 € 11,00 € 114,99 € 101,64 € 114,99 €
Словакия 11,00 € 9,60 € 11,00 € 114,99 € 100,80 € 114,99 €
Латвия 11,00 € 9,68 € 11,00 € 114,99 € 101,64 € 114,99 €
Словения 11,00 € 9,76 € 11,00 € 114,99 € 102,48 € 114,99 €
Эстония 11,00 € 9,60 € 11,00 € 114,99 € 100,80 € 114,99 €
Хорватия 11,00 € 10,00 € 11,00 € 114,99 € 105,00 € 114,99 €
Люксембург 11,00 € 9,28 € 11,00 € 114,99 € 97,44 € 114,99 €
Мальта 11,00 € 9,44 € 11,00 € 114,99 € 99,12 € 114,99 €
Кипр 11,00 € 9,52 € 11,00 € 114,99 € 99,96 € 114,99 €
Турция 209,00 ₺ 177,00 ₺ 209,00 ₺ 2199,00 ₺ 1,852,59 ₺ 2199,00 ₺
Мексика 200,00 $ 145,00 $ 200,00 $ 2100,00 $ 1520,00 $ 2100,00 $
Таиланд 380,00 ฿ 275,00 ฿ 380,00 ฿ 4000,00 ฿ 2900,00 ฿ 4000,00 ฿
Филиппины 600,00 ₱ 440,00 ₱ 600,00 ₱ 6300,00 ₱ 4600,00 ₱ 6300,00 ₱
Южно-Африканская Республика 200,00 R 144,99 R 200,00 R 2099,00 R 1519,00 R 2099,00 R
Аргентина 11,00 $ 8,00 $ 11,00 $ 114,99 $ 84,00 $ 114,99 $
Южная Корея 14 300 ₩ 10 400 ₩ 14 300 ₩ 150 000 ₩ 109 000 ₩ 150 000 ₩
Египет 339,00 LE 244,99 LE 339,00 LE 3500,00 LE 2549,00 LE 3500,00 LE
Нигерия 5000 ₦ 3650,00 ₦ 5000 ₦ 52 900 ₦ 38 500 ₦ 52 900 ₦
Малайзия 50,00 RM 35,00 RM 50,00 RM 519,90 RM 369,00 RM 519,90 RM
Колумбия 52 900 $ 38 500 $ 52 900 $ 554 900 $ 404 900 $ 554 900 $
Чили 8900 $ 6500 $ 8900 $ 92 990 $ 67 990 $ 92 990 $
Сингапур 15,00 $ 11,00 $ 15,00 $ 154,98 $ 112,98 $ 154,98 $
Объединенные Арабские Эмираты (ОАЭ) 40,00 dh 29,00 dh 40,00 dh 419,99 dh 309,00 dh 419,99 dh
Украина 11,00 $ 8,00 $ 406,00 грн 114,99 $ 84,00 $ 4245,00 грн
Кения 11,00 $ 8,00 $ 1419,00 Ksh 114,99 $ 84,00 $ 14 830 Ksh
Израиль 40,00 ₪ 29,00 ₪ 40,00 ₪ 419,00 ₪ 300,00 ₪ 419,00 ₪
Доминиканская Республика 11,00 $ 8,00 $ 11,00 $ 114,99 $ 84,00 $ 114,99 $
Швейцария 10,00 ₣ 7,00 ₣ 10,00 ₣ 105,00 ₣ 73,00 ₣ 105,00 ₣
Исландия 11,00 $ 8,00 $ 11,00 € 114,99 $ 84,00 $ 114,99 €
Норвегия 115,00 kr 83,00 kr 115,00 kr 1200,00 kr 870,00 kr 1200,00 kr
Афганистан 11,00 $ 8,00 $ Н/д 114,99 $ 84,00 $ Н/д
Албания 11,00 $ 8,00 $ 11,00 $ 114,99 $ 84,00 $ 114,99 $
Алжир 11,00 $ 8,00 $ 1495,00 DA 114,99 $ 84,00 $ 15 628 DA
Ангола 11,00 $ 8,00 $ 11,00 $ 114,99 $ 84,00 $ 114,99 $
Ангилья 11,00 $ 8,00 $ Н/д 114,99 $ 84,00 $ Н/д
Антигуа и Барбуда 11,00 $ 8,00 $ Н/д 114,99 $ 84,00 $ Н/д
Армения 11,00 $ 8,00 $ 11,00 $ 114,99 $ 84,00 $ 114,99 $
Аруба 11,00 $ 8,00 $ 11,00 $ 114,99 $ 84,00 $ 114,99 $
Азербайджан 11,00 $ 8,00 $ 11,00 $ 114,99 $ 84,00 $ 114,99 $
Багамские Острова 11,00 $ 8,00 $ 11,00 $ 114,99 $ 84,00 $ 114,99 $
Бахрейн 11,00 $ 8,00 $ 11,00 $ 114,99 $ 84,00 $ 114,99 $
Бангладеш Н/д 850,00 ৳ 1150,00 ৳ Н/д 8900,00 ৳ 12 100 ৳
Барбадос 11,00 $ 8,00 $ Н/д 114,99 $ 84,00 $ Н/д
Беларусь 11,00 $ 8,00 $ 11,00 $ 114,99 $ 84,00 $ 114,99 $
Белиз 11,00 $ 8,00 $ 11,00 $ 114,99 $ 84,00 $ 114,99 $
Бенин 11,00 $ 8,00 $ 11,00 € 114,99 $ 84,00 $ 114,99 €
Бермудские острова 11,00 $ 8,00 $ 11,00 $ 114,99 $ 84,00 $ 114,99 $
Бутан 11,00 $ 8,00 $ Н/д 114,99 $ 84,00 $ Н/д
Боливия 11,00 $ 8,00 $ 76,00 Bs 114,99 $ 84,00 $ 792,00 Bs
Босния и Герцеговина 11,00 € 8 EUR 11,00 $ 114,99 € 84 EUR 114,99 $
Ботсвана 11,00 $ 8,00 $ 11,00 $ 114,99 $ 84,00 $ 114,99 $
Британские Виргинские острова 11,00 $ 8,00 $ 11,00 $ 114,99 $ 84,00 $ 114,99 $
Бруней 11,00 $ 8,00 $ Н/д 114,99 $ 84,00 $ Н/д
Буркина-Фасо 11,00 $ 8,00 $ 11,00 € 114,99 $ 84,00 $ 114,99 €
Камбоджа 11,00 $ 8,00 $ 11,00 $ 114,99 $ 84,00 $ 114,99 $
Камерун 11,00 $ 8,00 $ 11,00 $ 114,99 $ 84,00 $ 114,99 $
Кабо-Верде 11,00 $ 8,00 $ 11,00 $ 114,99 $ 84,00 $ 114,99 $
Каймановы острова 11,00 $ 8,00 $ 11,00 $ 114,99 $ 84,00 $ 114,99 $
Центральноафриканская Республика Н/д 8 EUR 11,00 € Н/д 84 EUR 114,99 €
Чад 11,00 $ 8,00 $ 11,00 $ 114,99 $ 84,00 $ 114,99 $
Коморские Острова Н/д 8,00 $ 11,00 $ Н/д 84,00 $ 114,99 $
Демократическая Республика Конго (Киншаса) 11,00 $ 8,00 $ 11,00 $ 114,99 $ 84,00 $ 114,99 $
Республика Конго (Браззавиль) 11,00 $ 8,00 $ 11,00 $ 114,99 $ 84,00 $ 114,99 $
Коста-Рика 11,00 $ 8,00 $ 6000 ₡ 114,99 $ 84,00 $ 62 750 ₡
Кот-д'Ивуар 11,00 $ 8,00 $ 11,00 $ 114,99 $ 84,00 $ 114,99 $
Джибути Н/д 8,00 $ 11,00 $ Н/д 84,00 $ 114,99 $
Доминика 11,00 $ 8,00 $ 11,00 $ 114,99 $ 84,00 $ 114,99 $
Эквадор 11,00 $ 8,00 $ 11,00 $ 114,99 $ 84,00 $ 114,99 $
Сальвадор 11,00 $ 8,00 $ 11,00 $ 114,99 $ 84,00 $ 114,99 $
Экваториальная Гвинея 11,00 $ 8,00 $ Н/д 114,99 $ 84,00 $ Н/д
Эритрея Н/д 8,00 $ 11,00 $ Н/д 84,00 $ 114,99 $
Фиджи 11,00 $ 8,00 $ 11,00 $ 114,99 $ 84,00 $ 114,99 $
Габон 11,00 $ 8,00 $ 11,00 € 114,99 $ 84,00 $ 114,99 €
Гамбия 11,00 $ 8,00 $ 11,00 $ 114,99 $ 84,00 $ 114,99 $
Грузия 11,00 $ 8,00 $ 29,00 ₾ 114,99 $ 84,00 $ 297,00 ₾
Гана 11,00 $ 8,00 $ 11,00 $ 114,99 $ 84,00 $ 114,99 $
Гренада 11,00 $ 8,00 $ 11,00 $ 114,99 $ 84,00 $ 114,99 $
Гватемала 11,00 $ 8,00 $ 11,00 $ 114,99 $ 84,00 $ 114,99 $
Гвинея-Бисау 11,00 $ 8,00 $ 11,00 € 114,99 $ 84,00 $ 114,99 €
Гайана 11,00 $ 8,00 $ Н/д 114,99 $ 84,00 $ Н/д
Гаити Н/д 8,00 $ 11,00 $ Н/д 84,00 $ 114,99 $
Гондурас 11,00 $ 8,00 $ 11,00 $ 114,99 $ 84,00 $ 114,99 $
Гонконг 86,00 $ 63,00 $ 86,00 $ 900,00 $ 660,00 $ 900,00 $
Ирак 11,00 $ 8,00 $ 16 000 ID 114,99 $ 84,00 $ 167 100 ID
Ямайка 11,00 $ 8,00 $ 11,00 $ 114,99 $ 84,00 $ 114,99 $
Иордания 11,00 $ 8,00 $ 8000 JD 114,99 $ 84,00 $ 82 000 JD
Казахстан 5000,00 ₸ 3650,00 ₸ 5000,00 ₸ 52 490 ₸ 38 490 ₸ 52 490 ₸
Косово 11,00 € 8 EUR Н/д 114,99 € 84 EUR Н/д
Кувейт 11,00 $ 8,00 $ 11,00 $ 114,99 $ 84,00 $ 114,99 $
Киргизия 11,00 $ 8,00 $ 11,00 $ 114,99 $ 84,00 $ 114,99 $
Лаос 11,00 $ 8,00 $ 11,00 $ 114,99 $ 84,00 $ 114,99 $
Ливан 11,00 $ 8,00 $ 11,00 $ 114,99 $ 84,00 $ 114,99 $
Либерия 11,00 $ 8,00 $ 11,00 $ 114,99 $ 84,00 $ 114,99 $
Ливия 11,00 $ 8,00 $ 11,00 $ 114,99 $ 84,00 $ 114,99 $
Лихтенштейн Н/д 7,00 ₣ 10,00 ₣ Н/д 73,00 ₣ 105,00 ₣
Макао 11,00 $ 8,00 $ 89,00 MOP 114,99 $ 84,00 $ 929,00 MOP
Мадагаскар 11,00 $ 8,00 $ Н/д 114,99 $ 84,00 $ Н/д
Малави 11,00 $ 8,00 $ Н/д 114,99 $ 84,00 $ Н/д
Мальдивские Острова 11,00 $ 8,00 $ 11,00 $ 114,99 $ 84,00 $ 114,99 $
Мали 11,00 $ 8,00 $ 11,00 € 114,99 $ 84,00 $ 114,99 €
Мавритания 11,00 $ 8,00 $ Н/д 114,99 $ 84,00 $ Н/д
Маврикий 11,00 $ 8,00 $ 11,00 $ 114,99 $ 84,00 $ 114,99 $
Микронезия 11,00 $ 8,00 $ 11,00 $ 114,99 $ 84,00 $ 114,99 $
Молдова 11,00 $ 8,00 $ 11,00 $ 114,99 $ 84,00 $ 114,99 $
Монголия 11,00 $ 8,00 $ Н/д 114,99 $ 84,00 $ Н/д
Черногория 11,00 € 8 EUR Н/д 114,99 € 84 EUR Н/д
Монтсеррат 11,00 $ 8,00 $ Н/д 114,99 $ 84,00 $ Н/д
Марокко 11,00 $ 8,00 $ 11,00 $ 114,99 $ 84,00 $ 114,99 $
Мозамбик 11,00 $ 8,00 $ 11,00 $ 114,99 $ 84,00 $ 114,99 $
Мьянма 11,00 $ 8,00 $ 23 090 K 114,99 $ 84,00 $ 240 500 K
Намибия 11,00 $ 8,00 $ 11,00 $ 114,99 $ 84,00 $ 114,99 $
Науру 11,00 $ 8,00 $ Н/д 114,99 $ 84,00 $ 114,99 $
Непал 11,00 $ 8,00 $ 11,00 $ 114,99 $ 84,00 $ 114,99 $
Никарагуа 11,00 $ 8,00 $ 11,00 $ 114,99 $ 84,00 $ 114,99 $
Нигер 11,00 $ 8,00 $ 11,00 € 114,99 $ 84,00 $ 114,99 €
Северная Македония 11,00 $ 8,00 $ 11,00 $ 114,99 $ 84,00 $ 114,99 $
Оман 11,00 $ 8,00 $ 11,00 $ 114,99 $ 84,00 $ 114,99 $
Пакистан 3100 Rs 2250 Rs 3100 Rs 32 500 Rs 23 700 Rs 32 500 Rs
Палау 11,00 $ 8,00 $ Н/д 114,99 $ 84,00 $ Н/д
Панама 11,00 $ 8,00 $ 11,00 $ 114,99 $ 84,00 $ 114,99 $
Папуа — Новая Гвинея 11,00 $ 8,00 $ Н/д 114,99 $ 84,00 $ Н/д
Парагвай 11,00 $ 8,00 $ 80 000 ₲ 114,99 $ 84,00 $ 826 000 ₲
Перу 42,00 S/ 30,00 S/ 42,00 S/ 439,00 S/ 319,00 S/ 439,00 S/
Катар 40,00 QR 29,00 QR 40,00 QR 419,00 QR 304,99 QR 419,00 QR
Руанда 11,00 $ 8,00 $ 11,00 $ 114,99 $ 84,00 $ 114,99 $
Самоа Н/д 8,00 $ 11,00 $ Н/д 84,00 $ 114,99 $
Сан-Марино Н/д 8 EUR 11,00 € Н/д 84 EUR 114,99 €
Сан-Томе и Принсипи 11,00 $ 8,00 $ Н/д 114,99 $ 84,00 $ Н/д
Сенегал 11,00 $ 8,00 $ 11,00 $ 114,99 $ 84,00 $ 114,99 $
Сербия 11,00 € 8 EUR 11,00 € 114,99 € 84 EUR 114,99 €
Сейшельские Острова 11,00 $ 8,00 $ 11,00 $ 114,99 $ 84,00 $ 114,99 $
Сьерра-Леоне 11,00 $ 8,00 $ 11,00 $ 114,99 $ 84,00 $ 114,99 $
Соломоновы Острова 11,00 $ 8,00 $ 11,00 $ 114,99 $ 84,00 $ 114,99 $
Шри-Ланка 11,00 $ 8,00 $ 3740,00 Rs 114,99 $ 84,00 $ 39 080 Rs
Сент-Китс и Невис 11,00 $ 8,00 $ 11,00 $ 114,99 $ 84,00 $ 114,99 $
Сент-Люсия 11,00 $ 8,00 $ 11,00 $ 114,99 $ 84,00 $ 114,99 $
Сент-Винсент и Гренадины 11,00 $ 8,00 $ Н/д 114,99 $ 84,00 $ Н/д
Суринам 11,00 $ 8,00 $ 11,00 $ 114,99 $ 84,00 $ 114,99 $
Тайвань 335,00 $ 245,00 $ 335,00 $ 3500,00 $ 2550,00 $ 3500,00 $
Таджикистан 11,00 $ 8,00 $ 11,00 $ 114,99 $ 84,00 $ 114,99 $
Танзания 25 900 TSh 18 900 TSh 25 900 TSh 269 000 TSh 196 900 TSh 269 000 TSh
Того Н/д 8 EUR 11,00 € Н/д 84 EUR 114,99 €
Тонга 11,00 $ 8,00 $ 11,00 $ 114,99 $ 84,00 $ 114,99 $
Тринидад и Тобаго 11,00 $ 8,00 $ 11,00 $ 114,99 $ 84,00 $ 114,99 $
Тунис 11,00 $ 8,00 $ 11,00 $ 114,99 $ 84,00 $ 114,99 $
Туркменистан 11,00 $ 8,00 $ 11,00 $ 114,99 $ 84,00 $ 114,99 $
Теркс и Кайкос 11,00 $ 8,00 $ 11,00 $ 114,99 $ 84,00 $ 114,99 $
Уганда 11,00 $ 8,00 $ 11,00 $ 114,99 $ 84,00 $ 114,99 $
Уругвай 11,00 $ 8,00 $ 11,00 $ 114,99 $ 84,00 $ 114,99 $
Узбекистан 11,00 $ 8,00 $ 11,00 $ 114,99 $ 84,00 $ 114,99 $
Вануату 11,00 $ 8,00 $ 11,00 $ 114,99 $ 84,00 $ 114,99 $
Ватикан Н/д 8 EUR 11,00 € Н/д 84 EUR 114,99 €
Венесуэла 11,00 $ 8,00 $ 11,00 $ 114,99 $ 84,00 $ 114,99 $
Вьетнам 259 000 ₫ 189 000 ₫ 259 000 ₫ 2 699 000 ₫ 1 990 000 ₫ 2 699 000 ₫
Йемен 11,00 $ 8,00 $ 11,00 $ 114,99 $ 84,00 $ 114,99 $
Замбия 11,00 $ 8,00 $ 11,00 $ 114,99 $ 84,00 $ 114,99 $
Зимбабве 11,00 $ 8,00 $ 11,00 $ 114,99 $ 84,00 $ 114,99 $

Какого цвета ваша функция?

Не знаю как вам, но для меня нет лучшего начала дня, чем потрепаться о программировании. Кровь кипит при виде удачной критики одного из "жирных" языков, которым пользуются плебеи, мучаясь с ним на протяжении рабочего дня между стыдливыми посещениями StackOverflow.

(Тем временем, вы и я используем только самый просветленный язык и отточенные инструменты, разработанные для ловких рук таких мастеров, как мы).

Конечно, как автор проповеди, я иду на риск. Вам может нравиться язык, который я высмеиваю! Безрассудный памфлет мог бы неосторожно привлечь в мой блог яростную толпу черни с вилами и факелами наперевес.

Чтобы защититься от праведного огня и не оскорбить ваши (вероятно деликатные) чувства, я буду рассказывать о языке.

… который только что придумал. О соломенном чучеле, чья единственная роль — сгореть на костре критики.

Я знаю, что это звучит глупо, но поверьте, в конце мы увидим, чье лицо (или лица) были нарисованы на соломенной башке.

Новый язык

Будет перегибом учить совершенно новый (и отстойный) язык только для статьи в блоге, поэтому допустим, что он очень похож на язык, который мы уже знаем. Например Javascript. Фигурные скобки и точки с запятой. if , while и т.д. — Lingua franca нашей толпы.

Я выбрал JS не потому, что эта статья о нем. Просто это язык, в который среднестатистический читатель скорее всего врубается. Вуаля:

function thisIsAFunction()

Так как наше чучело — это крутой (читай — хреновый) язык, то он имеет функции первого класса. Так что вы можете написать что-то такое:

// вернуть список, содержащий все элементы из коллекции, // которые соответствуют условию function filter(collection, predicate) < var result = []; for (var i = 0; i < collection.length; i++) < if (predicate(collection[i]))< result.push(collection[i]); >> return result; >

Это одна из тех самых функций первого класса, и, как следует из названия, они классные и супер-полезные. Вы наверное привыкли преобразовывать коллекции данных с их помощью, но, как только ухватываешь концепцию, начинаешь использовать их везде, блин.

describe("Яблоко", function()< it("не апельсин", function()< expect("Яблоко").not.toBe("Апельсин"); >); >;

Или когда надо разобрать (распарсить) данные:

tokens.match(Token.LEFT_BRACKET, function(token)< // Parse a list literal. tokens.consume(Token.RIGHT_BRACKET); >);

Потом, разогнавшись, вы пишете все виды крутых переиспользуемых библиотек и приложений, крутящихся вокруг функций, вызовов функций, возвратов функций из функций — функциональный балаган.

переводчик: в оригинале "Functapalooza". Приставка-слово -a-palooza такое классное, что хочется им поделится для всех.

Какого цвета ваша функция?

И тут начинаются странности. Наш язык имеет одну своеобразную особенность:

1. Каждая функция имеет цвет.

Каждая функция — анонимный callback или обычная функция с именем — является или красной или синей. Так как подсветка кода в нашем блоге не выделяет разный цвет функций, давайте договоримся что синтакс такой:

blue*function doSomethingAzure() < // это синяя функция. >red*function doSomethingCarnelian()< // а это красная функция. >

У нашего языка нет бесцветных функций. Хотите сделать функцию? — должны выбрать цвет. Такие вот правила. И есть еще несколько правил, которым вы должны следовать:

2. Цвет влияет на способ вызова функции

Представьте, что есть два синтаксиса вызова функций — "синий" и "красный". Что-нибудь типа:

doSomethingAzure(. )*blue; doSomethingCarnelian()*red;

Когда вызываете функцию — вы должны использовать вызов, который соответствует её цвету. Если не угадали — вызвали красную функцию с *blue после скобок (или наоборот) — произойдет что-то очень плохое. Давно забытый детский кошмар, типа клоуна со змеями вместо рук, который прятался под вашей кроватью. Он выпрыгнет из монитора и высосет ваши глаза.

Дурацкое правило, правда? Ой, но вот еще одно:

3. Только красная функция может вызвать красную функцию.

Вы можете вызвать синюю функцию из красной. Это кошерно:

red*function doSomethingCarnelian()

Но не наоборот. Если вы попробуете:

blue*function doSomethingAzure()

— вас посетит старый Клоун Паучья Пасть.

Это делает сложнее написание высших функций, таких как filter() из примера. Мы должны выбрать цвет для каждой новой функции и это влияет на цвет функций, которые мы можем ей передать. Очевидное решение — сделать filter() красной. Тогда мы можем вызывать хоть красные, хоть синие функции. Но тогда мы поранимся о следующую колючку в терновом венце, которым является данный язык:

4. Красные функции больнее вызывать

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

Неважно что это, но если вы решили сделать функцию красной, каждый, кто использует ваш API, захочет плюнуть в ваш кофе или сделать чего похуже.

Очевидное решение в таком случае — никогда не использовать красные функции. Просто сделать все синим, и вы снова в нормальном мире, где все функции одного цвета, что равно тому, что у них нет цвета и что наш язык не совсем тупой.

Увы, но садисты, которые разработали данный язык (все знают, что авторы языков программирования являются садистами, правда?), втыкают в нас последний шип:

5. Некоторые функции ядра языка — красные.

Некоторые функции, встроенные в платформу, функции, которые нам нужно использовать, которые невозможно написать самим — доступны только в красном цвете. В этот момент разумный человек может начать подозревать, что этот язык ненавидит нас.

Это все вина функциональных языков!

Вы можете подумать, что проблема в том, что мы пытаемся использовать функции высшего порядка. Если мы просто перестанем валять дурака со всей этой функциональной ерундой, и начнем писать нормальные синие функции первого порядка (функции, которые не оперируют другими функциями — прим. переводчика), как и планировалось Богом — мы избавимся от всей этой боли.

Если мы вызываем только синие функции — делаем все наши функции синими. Иначе — делаем красными. Пока мы не создаем функции, которые принимают функции, нам не нужно беспокоиться о "полиморфности к цвету функции" (полихроматичность?) или других глупостях.

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

Например, у нас есть приятный маленький кусочек кода, который, ну я не знаю, реализует алгоритм Дейкстры над графом, представляющим как сильно ваши социальные связи давят друг на друга. (я потратил кучу времени, пытаясь решить, что бы означал результат. Транзитивная нежелательность?)

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

Допустим, что новое место, из которого вы хотите вызывать функцию — синее? Но теперь вам нужно переписать вызывающий код в красный. И потом переделать функцию, которая вызывает этот код. Уф. Вам придется постоянно помнить про цвет в любом случае. Это будет песком в ваших плавках на пляжном отдыхе программирования.

Цветная аллегория

На самом деле я тут не про цвет говорю. Это аллегория, литературный прием. Сничи — это не про звезды на животиках, это про расу. Вы уже наверное подозреваете .

Красные функции — асинхронные

Если вы программируете на JavaScript или Node.js, каждый раз, определяя функцию, которая вызывает функцию обратного вызова (коллбэк), чтобы "вернуть" результат — вы пишете красную функцию. Посмотрите на этот список правил и заметьте, как они укладываются в мою метафору:

  1. Синхронные функции возвращают результат, асинхронные — нет, взамен они вызывают коллбэк.
  2. Синхронные функции выдают результат как возвращаемое значение, асинхронные выдают его, вызывая коллбек, который вы им передали.
  3. Вы не можете вызвать асинхронную функцию из синхронной, потому, что вы не сможете узнать результат, пока асинхронная функция не выполнится позже.
  4. Асинхронные функции не составляются в выражения из-за коллбэков, требуют иначе обрабатывать их ошибки и не могут быть использованы в try/catch блоке или в ряде других выражений, управляющих программой.
  5. вся фишка Node.js в том, что библиотека ядра вся асинхронная. (Хотя они сдают назад и начали добавлять _Sync() версии множеству вещей.)

Когда люди рассказывают про "ад обратных вызовов" — они говорят о том, как досадно иметь "красные" функции в их языке. Когда они создают 4089 библиотек для асинхронного программирования (в 2019-м уже 11217 — прим. Переводчика), они пытаются на уровне библиотеки совладать с проблемой, которую им всучили вместе с языком.

I promise the future is better

в переводе: "Я обещаю, что будущее лучше" теряется игра слов из названия и содержимого раздела

Люди в обществе Node.js уже давно осознали, что коллбэки это больно, и искали решения. Одна из техник, которая воодушевила многих людей, это promises , которые вы также можете знать по кличке futures .

в русском IT вместо перевода "promises" как "обещания", установилась калька с английского — "промисы". Слово "Futures" же используется, как есть, вероятно потому что "фьючерсы" уже заняты финансовым сленгом.

Промис это обертка для коллбэка и обработчика ошибок. Если вы думаете о передаче коллбэка для результата и другого коллбэка для ошибки, то future является воплощением этой идеи. Это базовый объект, который представляет собой асинхронную операцию.

Я только что разродился кучей причудливых формулировок и это может звучать как отличное решение, но в основном это змеиное масло. Промисы и правда позволяют писать асинхронный код чуть проще. Их проще составлять в выражения, так что правило №4 немного менее жесткое.

Но, если честно, это как разница между ударом в живот или в пах. Да, это не так больно, но никто не будет в восторге от подобного выбора.

Вы все еще не можете использовать промисы с обработкой исключений или другими
управляющими операторами. Вы не можете вызывать функцию, которая возвращает future , из синхронного кода. (вы таки можете, но тогда следующий майнтейнер вашего кода изобретет машину времени, вернется в момент, когда вы это сделали, и воткнет вам в лицо карандаш по причине №2.)

Промисы все еще делят ваш мир на асинхронную и синхронную половинки со всем вытекающим из этого страданием. Так что, если даже ваш язык поддерживает promises или futures , он все еще очень похож на мое чучело.

(Да, это включает даже Dart, который я использую. Поэтому я так рад, что часть команды пробует другие подходы к параллельности)

проект по ссылке официально заброшен

I'm awaiting a solution

Программисты С#, вероятно, чувствуют себя самодовольно (причина, по которой они все более становятся жертвами, это то, что Хейлсберг и компания все посыпают и посыпают язык синтаксическим сахаром). В C# вы можете использовать ключевое слово await , чтобы вызвать асинхронную функцию.

Это позволяет делать асинхронные вызовы так же легко, как синхронные, с добавлением милого маленького ключевого слова. Вы можете вставить вызов await в выражениях, использовать их в обработке исключений, в инструкциях потока выполнения. Можете сходить с ума. Пусть await'ы польются дождем, как баксы за ваш новый рэперский альбом.

Async-await приятный, поэтому мы добавляем его в Dart. С ним гораздо легче писать асинхронный код. Но, как всегда, есть одно "Но". Вот оно. Но. вы все еще делите мир пополам. Асинхронные функции теперь легче писать, но они все еще асинхронные функции.

У вас все еще два цвета. Async-await решают досадную проблему №4 — они делают вызов красных функций не труднее вызова синих. Но остальные правила все еще здесь:

  1. Синхронные функции возвращают значения, асинхронные возвращают обертку ( Task в С# или Future в Dart) вокруг значения.
  2. Синхронные просто вызываются, асинхронным нужен await .
  3. Вызывая асинхронную функцию, вы получаете объект-обертку, когда на самом деле вы хотите значение. Вы не можете развернуть значение, пока вы не сделаете вашу функцию асинхронной и не вызовете ее с await (но см. следующий пункт).
  4. Помимо небольшого украшения await'ом, по крайней мере эту проблему мы решили.
  5. Библиотека ядра C# старше, чем асинхронность, так что я думаю, они никогда не имели этой проблемы.

Async действительно лучше. Я предпочту async-await голым коллбэкам в любой день недели. Но мы лжем себе, если думаем, что все проблемы решены. Как только вы начинаете писать функции высшего порядка, или переиспользовать код — вы снова понимаете, что цвет все еще там, кровоточит через весь ваш исходный код.

Какой язык не цветной?

Итак JS, Dart, C# и Python имеют эту проблему. CoffeeScript и большинство других языков, компилирующихся в JS — тоже (и Dart унаследовал). Я думаю, даже у ClojureScript есть эта загвоздка, несмотря на их активные старания с core.async

Хотите знать, какой не имеет? Java. Я прав? Как часто вы говорите — "да уж, Java единственная делает это правильно"? И вот это случилось. В их защиту, они активно пытаются исправить свою оплошность, продвигая futures и async IO. Это как гонка "кто хуже".

C#, на самом деле, тоже может обойти эту проблему. Они выбрали иметь цвет. До того, как они добавили async-await и все это Task барахло, вы могли просто использовать обычные синхронные вызовы API. Три других языка, которые не имеют "цветной" проблемы: Go, Lua и Ruby.

Догадываетесь, что у них общего?

Потоки. Или, более точно: множество независимых стеков вызовов, которые могут переключатся. Это не обязательно потоки операционной системы. Корутины в Go, корутины в Lua и нити в Ruby — все вполне адекватны.

(Вот почему для C# есть эта маленькая оговорка — вы можете избежать асинхронной боли в C#, используя потоки.)

Память о прошлых операциях

Фундаментальная проблема это "как продолжить с того же места, когда (асинхронная) операция завершится"? Вы погрузились в пучину стека вызовов и потом вызвали какую-то операцию ввода-вывода. Ради ускорения, эта операция использует нижележащий асинхронный API вашей ОС. Вы не можете ждать, пока она завершится. Вы должны вернуться к циклу событий вашего языка и дать ОС время, чтобы выполнить операцию.

Как только это произойдет, вам нужно возобновить то, что вы делали. Обычно язык "вспоминает где это было" через стек вызовов. Он следует через все функции, которые на данный момент были вызваны, и смотрит, куда показывает счетчик команд в каждой из них.

Но, чтобы выполнить асинхронный ввод-вывод, вы должны размотать, отбросить весь стек вызовов в языке С. Типа Уловка-22. У вас супер быстрый ввод-вывод, но вы не можете использовать результат! Все языки с асинхронным вводом-выводом под капотом — или, в случае JS, циклом событий браузера — вынуждены как-то справлятся с этим.

Node, с его "вечно-марширующими-вправо" коллбэками, запихивает все эти вызовы в замыкания. Когда вы пишете:

function makeSundae(callback) < scoopIceCream(function (iceCream) < warmUpCaramel(function (caramel) < callback(pourOnIceCream(iceCream, caramel)); >); >); >

Каждое из этих функциональных выражений замыкает весь свой окружающий контекст. Это переносит параметры, такие как iceCream и caramel , из стека вызовов в кучу. Когда внешняя функция возвращает результат и стек вызовов уничтожен, это круто. Данные всё ещё гдето в куче.

Проблема в том, что вы должны снова воскресить каждый из этих чертовых вызовов. Есть даже специальное название для этого преобразования: continuation-passing style

по ссылке лютая функциональщина

Это изобрели языковые хакеры в 70-х, как промежуточное представление для использования под капотом компиляторов. Это очень причудливый способ представить код, который облегчает выполнение некоторых оптимизаций компилятора.

Никто никогда не думал, что программист может писать подобный код. А потом появился Node, и внезапно мы все притворяемся, что пишем бекэнд компилятора. Где мы свернули не туда?

Заметьте, что промисы и futures мало чем помогают на самом деле. Если вы используете их, вы знаете, что по прежнему нагромождаете гигантские пласты функциональных выражений. Вы просто передаете их в .then() вместо самой асинхронной функции.

Awaiting a generated solution

Async-await действительно помогает. Если заглянуть под капот компилятору, когда он встречает await , вы увидите, что он фактически выполняет CPS-преобразование. Вот почему вам нужно использовать await в C# — это подсказка компилятору — "остановите функцию здесь посередине". Все, что после await , становится новой функцией, которую компилятор синтезирует от вашего имени.

Вот почему async-await не нуждается в поддержке среды выполнения внутри .NET фреймворка. Компилятор компилирует это в цепочку связанных замыканий, которые он уже умеет обрабатывать. (Интересно, что замыканиям тоже не требуется поддержка среды выполнения. Они компилируются в анонимные классы. В C# замыкания — это просто объекты.)

Вам наверное интересно, когда я упомяну генераторы. В вашем языке есть yield ? Тогда он может делать чтото очень похожее.

(я считаю, что генераторы и async-await изоморфны на самом деле. Где-то в пыльных закоулках моего жесткого диска валяется кусок кода, в котором реализован игровой цикл на генераторах с использованием только async-await.)

Так, где это я? Ах да. Так что с коллбэками, промисами, async-await и генераторами, вы кончаете тем, что берете свою асинхронную функцию и разбиваете ее в пачку замыканий, которые живут в куче.

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

Вот откуда берется правило "вызвать красную функцию можно только из красной функции". Вы должны сохранить в замыканиях весь стек вызовов до самого main() или обработчика событий.

Реализация стека вызовов

Но используя треды (зеленые или уровня ОС), вам не нужно это делать. Вы можете просто приостановить весь тред и прыгнуть к ОС или циклу событий без необходимости возвращаться из всех этих функций.

Язык Go, в моем понимании, делает это наиболее совершенно. Как только вы делаете любую операцию ввода-вывода, Go паркует эту корутину и продолжает любую другую, которая не заблокирована вводом-выводом.

Если посмотреть на операции ввода-вывода в стандартной библиотеке Golang, они кажутся синхронными. Другими словами, они просто работают и потом возвращают результат, когда готовы. Но эта синхронность не означает то же, что в Javascript. Другой Go-код может работать, пока мы ждем IO операцию. Так Go устранил различие между синхронным и асинхронным кодом.

Параллелизм в Go — это как вы выбираете моделировать вашу программу, а не цвет каждой функции в стандартной библиотеке. Это значит что вся боль пяти правил, которые я упомянул, полностью и абсолютно устранена.

Так что в следующий раз, как вы решите рассказать мне историю о новом популярном языке и его крутом асинхронном API, вы будете знать, почему я начинаю скрежетать зубами. Потому что мы снова вернулись к нашим красным и синим баранам.

От переводчика

Язык автора, его саркастичные метафоры и мастерская игра слов показались мне настолько хороши, что было бы упущением не познакомить с ним русскоязычного читателя. Зная английский на уровне чуть выше среднего, вы получите огромное удовольствие от чтения в оригинале. Надеюсь, мне удалось передать хотя бы 50% авторского юмора и перевод не стал при этом слишком тяжеловесным.

Я, как упомянутый в статье средний программист, несколько раз пытался писать асинхронный код, но каждый раз натыкался на острые шипы асинхронных функций и их интерфейсов и собирал все вышеперечисленные грабли.

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

Но вот в моем любимом Питоне, сколько бы я ни брался (на самом деле всего пару раз) за асинхронность — вместо удовольствия, которое я получаю от программирования, я получал непонимание, где нужен и где не нужен этот async и как это все втиснуть в существующие синхронные программы. Обычно я заканчивал с import threading и переставал забивать себе голову (а может быть, мне просто еще не попался в работе проект на AsyncIO, Twisted или Tornado, чтобы въехать в тему).

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

Боб как будто полил бальзамом мои раны, мне даже захотелось выучить Go, несмотря на все критикующие Go статьи.

Уж точно, что я не один такой программист средней руки, которому кажется, что (вероятно из-за врожденного асинхронного порока мозга) он один не может легко и просто начать применять асинхронность, несмотря на толпу гуру со всеми их статьями про "async-await для чайников". Для них и сделан этот перевод.

Обратная связь горячо приветствуется, надеюсь мы еще улучшим этот текст вместе.

Надеюсь, что другие статьи Боба так же хороши, и мне захочется переводить еще.

Найдите ваш любимый снимок из множества фотографий -- Предоставление общего доступа и централизованное управление по вашему желанию

Приложение PlayMemories Home от Sony позволяет упорядочивать и редактировать на ПК фотографии и видео.
Упорядочивайте ваши фотографии и видео по дате съемки,
использованной камере или объективу и другим характеристикам.
Эффективный поиск и функции предоставления общего доступа позволят вам легко обходиться с вашими фотографиями

Установка PlayMemories Home (версия 6.0.00) (64-разрядная версия)

При обновлении с версий, предшествующих версии 6.0, некоторые функции станут недоступны.
Дополнительные сведения см. в разделе "Краткое содержание обновления".

Начиная с конца марта 2020 г. PlayMemories Home версии 5.5 (для 32-разрядных ОС) больше недоступно для загрузки с 31 марта 2020 года.
Action Cam Movie Creator больше недоступно для загрузки с 31 марта 2022 года.

Следующие устройства не поддерживаются:
ILCE-1, ILCE-7SM3, ILCE-7RM5, ILCE-7CR, ILCE-7CM2, ILCE-7C, ILCE-7M4, ILCE-6700, ZV-E1, ZV-E10, ZV-1F, ZV-1M2, ILME-FX6, ILME-FX30, ILME-FX3

Поддержка PlayMemories Home здесь

Рекомендуемая среда компьютера указана здесь

Загрузка версии Mac здесь

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *