Callout и Callback — приложения для исходящих звонков с мобильного телефона
Сотрудник сначала осуществляет исходящий звонок с мобильного на виртуальный номер, затем вводит номер абонента, которому необходимо позвонить, и виртуальная АТС автоматически их соединяет. Удобно использовать, если на мобильном используется безлимитный тариф на исходящую связь.
Сотрудник сначала осуществляет исходящий звонок с мобильного на виртуальный номер, виртуальная АТС сбрасывает звонок, автоматически перезванивает сотруднику на мобильный, сотрудник вводит номер абонента, которому необходимо позвонить, и виртуальная АТС автоматически их соединяет. Удобно использовать за границей, чтобы не платить мобильному оператору за роуминг.
Как настроить
В первую очередь в разделе «Виртуальные номера и правила» выберите номер, который хотите транслировать в качестве исходящего и перейдите в режим редактирования:
Кликните на «Создать правило» и выберите приложение, которое хотите использовать:
Callout
Кликните на «Добавить номер абонента» и введите в появившееся поле номер сотрудника, с которого будет осуществляться исходящий звонок. Поле «PIN-код для авторизации» позволяет сгенерировать код, который нужно будет ввести сотруднику перед набором номера абонента. Поле не является обязательным, его можно не заполнять.
После сохранения настроек, при звонке с указанного мобильного номера на виртуальный номер, сотрудник услышит фразу «Введите номер абонента». Номер можно вводить как обычно, начиная с 8. После ввода номера абонента необходимо нажать клавишу #.
В случае, если используется PIN-код авторизации, сотрудник услышит фразу «Введите авторизационный код», и только после корректного ввода — «Введите номер абонента».
Callout будет срабатывать только для тех, чей номер внесен в настройку правила. Входящие звонки на виртуальный номер от всех остальных абонентов будут обрабатываться в соответствии с настроенными сценариями.
Callback
Включите настройку «только для номеров из списка», если не хотите, чтобы все абоненты, звонящие на виртуальный номер, использовали Callback. Кликните на «Добавить номер абонента» и введите в появившееся поле номер сотрудника, с которого будет осуществляться исходящий звонок. Дополнительно можно выбрать число попыток дозвона от виртуальной АТС до номера сотрудника на случай, если его номер будет занят или потеряет сеть.
После сохранения настроек, при звонке с указанного мобильного номера на виртуальный номер, сотрудник услышит фразу «Ожидайте входящий звонок», и звонок завершится. После этого на мобильный сотрудника поступит входящий вызов, и сотрудник услышит фразу «Введите номер абонента». Номер можно вводить как обычно, начиная с 8. После ввода номера абонента необходимо нажать клавишу #.
Callback будет срабатывать только для тех, чей номер внесен в настройку правила. Входящие звонки на виртуальный номер от всех остальных абонентов будут обрабатываться в соответствии с настроенными сценариями.
Сколько стоит
Оба приложения доступны по умолчанию на всех тарифах.
Тарификация звонков через Callout осуществляется в два плеча:
- от мобильного телефона до виртуальной АТС — оплачивается мобильному оператору, причем за всю длительность разговора;
- от виртуальной АТС до конечного абонента — оплачивается в UIS по тарифам исходящей связи.
Тарификация звонков через Callback осуществляется в три плеча:
- от мобильного телефона до виртуальной АТС — не тарифицируется, т.к. виртуальная АТС сбрасывает звонок;
- от виртуальной АТС до мобильного номера сотрудника — оплачивается в UIS по тарифам исходящей связи;
- от виртуальной АТС до конечного абонента — оплачивается в UIS по тарифам исходящей связи.
Коллбэк в JavaScript… Что за зверь?
Если вы не очень хорошо представляете себе — что такое «коллбэки», и как ими пользоваться в JavaScript, сейчас у вас есть шанс их понять и научиться с ними работать.
Перейдём сразу к делу. Коллбэк — это функция, которая должна быть выполнена после того, как другая функция завершит работу. Отсюда и название, которое, в английском написании, может быть представлено как «call back», хотя обычно это — «callback». Среди вариантов перевода этого слова — «обратный вызов». В русскоязычных публикациях, допускающих использование жаргона программистов, весьма распространена калька с оригинального названия: «коллбэк». Если же обойтись без жаргона, то о чём мы говорим, называется «функция обратного вызова».
Углубившись, для объяснения сущности функций обратного вызова, в особенности JavaScript, можно сказать, что функции в JS — это объекты. Поэтому функции могут принимать другие функции в качестве аргументов и возвращать их в качестве результатов. Функции, которые работают подобным образом, называют функциями высшего порядка. Коллбэками же обычно называют функции, передаваемые другим функциям в качестве аргументов.
Зачем нужны функции обратного вызова?
Коллбэки нужны по одной очень важной причине: JavaScript — это язык, в котором огромную роль играют события. Это означает, что вместо того, чтобы ожидать, скажем, результата выполнения некоей функции, остановив при этом все остальные операции, JavaScript-программа работает, наблюдая за событиями и реагируя на них.
Взглянем на простой пример:
function first() < console.log(1); >function second() < console.log(2); >first(); second();
Как можно ожидать, функция first() выполняется первой, а функция second() — второй. Запуск этого кода приводит к тому, что в консоль будет выведено следующее:
// 1 // 2
Пока, надеемся, всё понятно, но что, если функция first() содержит код, который нельзя выполнить немедленно? Например, там есть обращение к некоему API, причём, сначала нужно отправить запрос, а потом дождаться ответа? Для того, чтобы это сымитировать, воспользуемся функцией setTimeout() , которая применяется в JavaScript для вызова других функций с заданной задержкой. Мы собираемся отложить вызов функции на 500 миллисекунд.
Вот что получилось теперь:
function first()< // Имитируем задержку setTimeout( function()< console.log(1); >, 500 ); > function second() < console.log(2); >first(); second();
Для наших целей особенности работы setTimeout() сейчас неважны. Главное — обратите внимание на то, что вызов console.log(1) будет выполнен с задержкой.
Вот что произойдёт при запуске этого кода:
// 2 // 1
Несмотря на то, что функция first() была вызвана первой, сначала в лог попало то, что выводит функция second() .
Это не значит, что JavaScript вызывает функции не в том порядке, в котором мы расположили их вызовы в коде. Смысл в том, что система переходит к исполнению функции second() , не дожидаясь ответа от функции first() .
В ситуациях, когда, вызвав некую функцию, нельзя быть уверенным в том, что программа продолжит работу только получив ответ от неё, использование функций обратного вызова — это подход, позволяющий гарантировать то, что некий фрагмент кода будет вызван только после того, как какой-то другой код завершит выполнение. Например, такое постоянно происходит в любой программе, которая так или иначе взаимодействует с внешним миром — скажем, с веб-сервисами.
Создаём функцию обратного вызова
Создадим собственную функцию обратного вызова.
Для начала — откройте консоль разработчика Chrome ( Ctrl + Shift + J в Windows, или Cmd + Option + J в Mac) и введите следующее:
function doHomework(subject) < alert(`Starting my $homework.`); >
Тут мы объявили функцию doHomework() . Эта функция принимает одну переменную — название предмета, по которому некто делает домашнюю работу. Вызовите функцию, введя в консоли следующее:
doHomework('math'); // Выводит сообщение: Starting my math homework.
Теперь добавим, в качестве второго аргумента функции doHomework() , параметр callback , который будем использовать для того, чтобы передать doHomework() функцию обратного вызова. Теперь код будет выглядеть так:
function doHomework(subject, callback) < alert(`Starting my $homework.`); callback(); >
Вызовем обновлённую функцию следующими образом:
doHomework('math', function() < alert('Finished my homework'); >);
Сначала будет выведено сообщение с текстом Starting my math homework. , потом — с текстом Finished my homework .
Функции обратного вызова совсем необязательно создавать непосредственно при вызове функций, которым они передаются. Такую функцию можно объявить и где-нибудь в коде:
function doHomework(subject, callback) < alert(`Starting my $homework.`); callback(); > function alertFinished() < alert('Finished my homework'); >doHomework('math', alertFinished);
После вызова функции doHomework() всё будет выглядеть точно так же, как в предыдущем примере. Различия заключаются лишь в том, как мы работаем с функцией обратного вызова.
Как вы можете видеть, тут, в качестве аргумента при вызове функции doHomework() , использовано имя функции alertFinished() .
Функции обратного вызова в реальных проектах
Для программного взаимодействия с популярной социальной сетью Twitter используется специальное API. Выполняя обращения к этому API, мы вынуждены ждать ответа, и только после его получения можем выполнять с тем, что придёт от Twitter, какие-то действия. Вот материал, где рассмотрена работа с Twitter API в среде Node.js с использованием NPM-пакета twitter.
Рассмотрим фрагмент кода из этого материала. Полагаем, он является отличной демонстрацией практического применения функций обратного вызова.
T.get('search/tweets', params, function(err, data, response) < if(!err)< // Именно здесь можно работать с тем, что вернёт нам Twitter >else < console.log(err); >>) T.get()
— это функция, которая выполняет get-запрос к Twitter API. У функции три аргумента. Первый — ‘search/tweets’ , представляет собой маршрут запроса. Здесь мы собираемся выполнить поиск по твитам. Второй аргумент — params — это параметры поиска. Третий аргумент — анонимная функция, которая и является функцией обратного вызова.
Функция обратного вызова здесь весьма важна, так как, прежде чем продолжать работу, нужно дождаться ответа от сервера. Неизвестно, будет ли обращение к API успешным, поэтому, после отправки параметров поиска по маршруту search/tweet с помощью get-запроса, приходится ждать. Как только Twitter ответит на запрос, будет выполнена функция обратного вызова. Если что-то пошло не так, в ней мы получим объект ошибок ( err ). Если запрос обработан нормально, в аргументе err будет значение, эквивалентное false , а значит, во-первых, будет исполнена ветвь if условного оператора, а во-вторых — можно будет рассчитывать на то, что в объекте response окажутся некие полезные данные, с которыми уже можно что-то делать.
Итоги
Надеемся, наш рассказ о функциях обратного вызова в JavaScript оказался полезен тем, кто не очень хорошо в них разбирался. На самом деле, то, о чём мы здесь говорили — это лишь вершина айсберга. Однако теперь, поняв основы, вы можете расширять и углублять свои знания в этой области.
Уважаемые читатели! Если вы из тех, кто, до чтения этого материала, плохо представлял себе, что такое функции обратного вызова в JS, скажите — стало понятнее? А если коллбэки для вас — обычное дело, просим поделиться опытом с новичками.
- JavaScript
- программирование
- функция обратного вызова
- коллбэк
- Блог компании RUVDS.com
- JavaScript
Понимание callback-функций (колбеков)
Callback-функции чрезвычайно важны в языке Javascript. Они есть практически повсюду. Но, несмотря на имеющийся опыт программирования на C/Java, с ними у меня возникли трудности (как и с самой идеей асинхронного программирования), и я решил в этом разобраться. Странно, но я не смог найти в интернете хороших вводных статей о callback-функциях — в основном попадались отрывки документации по функциям call() и apply() или короткие кусочки кода, демонстрирующие их использование, и вот, набив шишек в поисках истины, я решил написать введение в callback-функции самостоятельно.
Функции — это объекты
Чтобы понимать callback-функции, нужно понимать обычные функции. Это может показаться банальностью, но функции в Javascript’е — немного странные штуки.
Функции в Javascript’е — на самом деле объекты. А именно, объекты класса Function , создаваемые конструктором Function . В объекте Function содержится строка с JS-кодом данной функции. Если вы перешли с языка C или Java, это может показаться странным (как код может быть строкой?!), но, вообще говоря, в Javascript’е такое сплошь и рядом. Различие между кодом и данными иногда размывается.
// можно создать функцию, передав в конструктор Function строку с кодом var func_multiply = new Function("arg1", "arg2", "return arg1 * arg2;"); func_multiply(5, 10); // => 50
Преимущество концепции «функция-как-объект» заключается в том, что код можно передавать в другую функцию точно так же, как обычную переменную или объект (потому что в буквальном понимании код — всего лишь объект).
Передача функции как callback-функции
Передавать функцию в качестве аргумента просто.
// определяем нашу функцию с аргументом callback function some_function(arg1, arg2, callback) < // переменная, генерирующая случайное число в интервале между arg1 и arg2 var my_number = Math.ceil(Math.random() * (arg1 - arg2) + arg2); // теперь всё готово и мы вызываем callback, куда передаём наш результат callback(my_number); >// вызываем функцию some_function(5, 15, function (num) < // эта анонимная функция выполнится после вызова callback-функции console.log("callback called! " + num); >);
Может показаться глупостью создавать такой перемудрённый код, когда можно вернуть значение нормальным способом, но существуют ситуации, в которых это непрактично и callback-функции необходимы.
Не загромождайте выход
Традиционно функции в ходе выполнения принимают на вход аргументы и возвращают значение, используя выражение return (в идеальном случае единственное выражение return в конце функции: одна точка входа и одна точка выхода). Это имеет смысл. Функции — это, в сущности, маршруты между вводом и выводом.
Javascript даёт возможность делать всё немного по-другому. Вместо того чтобы дожидаться, пока функция закончит выполняться и вернёт значение, мы можем использовать callback-функции, чтобы получить его асинхронно. Это полезно для случаев, когда требуется много времени для завершения, например, при AJAX-запросах, ведь мы не можем приостановить браузер. Мы можем продолжить заниматься другими делами в ожидании вызова колбека. Фактически, очень часто от нас требуется (или, точнее, нам настоятельно рекомендуется) делать всё асинхронно в Javascript’е.
Вот более детальный пример, в котором используется AJAX для загрузки XML-файла и используется функция call() для вызова callback-функции в контексте запрошенного объекта (это значит, что когда мы укажем ключевое слово this внутри callback-функции, оно будет ссылаться на запрошенный объект):
function some_function2(url, callback) < var httpRequest; // создаём наш XMLHttpRequest-объект if (window.XMLHttpRequest) < httpRequest = new XMLHttpRequest(); >else if (window.ActiveXObject) < // для дурацкого Internet Explorer'а httpRequest = new ActiveXObject("Microsoft.XMLHTTP"); >httpRequest.onreadystatechange = function () < // встраиваем функцию проверки статуса нашего запроса // это вызывается при каждом изменении статуса if (httpRequest.readyState === 4 && httpRequest.status === 200) < callback.call(httpRequest.responseXML); // вызываем колбек >>; httpRequest.open('GET', url); httpRequest.send(); > // вызываем функцию some_function2("text.xml", function () < console.log(this); >); console.log("это выполнится до вышеуказанного колбека");
В этом примере мы создаём объект httpRequest и загружаем файл XML. Типичная парадигма возвращения значения в конце функции тут больше не работает. Наш запрос обрабатывается асинхронно, а это означает, что мы начинаем запрос и говорим ему вызвать нашу функцию, как только он закончится.
Мы используем здесь две анонимных функции. Важно помнить, что нам бы не составило труда использовать и именованные функции, но во имя лаконичности мы сделали их вложенными. Первая анонимная функция выполняется всякий раз при изменении статуса в нашем объекте httpRequest. Мы игнорируем это до тех пор, пока состояние не будет равно 4 (т.е. запрос выполнен) и статус будет равен 200 (т.е. запрос выполнен успешно). В реальном мире вам бы захотелось проверить, не провален ли запрос, но мы предполагаем, что файл существует и может быть загружен браузером. Эта анонимная функция связана с httpRequest.onreadystatechange, так что она выполняется не сразу, а вызывается каждый раз при изменении состояния в нашем запросе.
Когда мы наконец завершаем наш AJAX-запрос, мы не просто запускаем callback-функцию, мы используем для этого функцию call() . Это ещё один способ вызова callback-функции. Метод, использованный нами до этого — простой запуск функции здесь сработал бы хорошо, но я подумал, что стоит продемонстрировать и использование функции call() . Как вариант, можно использовать функцию apply() (обсуждение разницы между ней и call() выходят за рамки этой статьи, скажу лишь, что это затрагивает способ передачи аргументов функции).
В использовании call() замечательно то, что мы сами устанавливаем контекст, в котором выполняется функция. Это означает, что когда мы используем ключевое слово this внутри нашей callback-функции, оно ссылается на то, что мы передаём первым аргументом в call() . В данном примере, когда мы ссылались на this внутри нашей анонимной функции, мы ссылались на responseXML, полученный в результате AJAX-запроса.
Наконец, второе выражение console.log выполнится первым, потому что callback-функция не выполняется до тех пор, пока не закончен запрос, и пока это произойдёт, последующие части кода продолжают спокойно выполняться.
Обёртывай это
Надеюсь, теперь вы стали понимать callback-функции достаточно хорошо, чтобы начать их использовать в своём собственном коде. Мне всё ещё трудно структурировать код, который зиждется на callback-функциях (в конце концов он становится похож на спагетти… мой разум слишком привык к обычному структурному программированию), но они — очень мощный инструмент и одна из интереснейших частей языка Javascript.
При подготовке материала использовались источники:
https://www.uiscom.ru/academiya/spravochnyj-centr/obshchie-nastroyki/callout-i-callback-prilozheniya-dlya-iskhodyashchikh-zvonkov-s-mobilnogo-telefona/
https://habr.com/ru/companies/ruvds/articles/330880/
https://habr.com/ru/articles/151716/