Как найти человека по комментариям вк. Как посмотреть все комментарии Вконтакте? Как найти понравившиеся вам комментарии ВКонтакте

Сегодня каждый день появляются новые языки программирования - Go, Rust, CoffeeScript - все, что угодно. Я решил, что я тоже горазд придумать свой язык программирования, что миру не хватает какого-то нового языка…

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

Что в нем не очень обычно, что может даже оттолкнуть, на первый взгляд, - это то, что в Schlecht!Script функции имеют цвет.


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

Функции бывают красные и синие - двух цветов.

Важный момент: внутри синих функций вы можете вызывать только другие синие функции. Вы не можете вызывать красные функции внутри синих функций.


Внутри красных функций вы можете вызывать и красные, и синие функции.


Я решил, что должно быть так. В каждом языке должно быть так.

Тонкий момент: красные функции писать и вызывать больно! Что я имею в виду, когда говорю «больно»? Дело в том, что сейчас я изучаю немецкий язык, и я решил, что красные функции мы должны все называть только на немецком языке, иначе интерпретатор просто не поймет, что вы ему пытаетесь впихнуть, и он просто не будет это выполнять.


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


«!» обязателен - мы же на немецком пишем, в конце концов.

Как писать на таком языке? У нас есть два способа. Мы можем использовать только синие функции, в которые писать не больно, но внутри мы не можем пользоваться красными функциями. Этот подход не будет работать, потому что в порыве вдохновения я написал половину стандартной библиотеки на красных функциях, так что, простите…

Вопрос к вам - стали бы вы использовать такой язык? Продал ли я вам Schlecht!Script?

Ну, у вас, как бы, нет выбора. Простите…

JavaScript - отличный язык, мы все его любим, мы все здесь собрались, потому что мы любим JavaScript. Но проблема в том, что JavaScript наследует некоторые черты Schlecht!Script, и я, конечно, не хочу хвастаться, но, по-моему, они украли пару моих идей.

Что именно они наследуют? в JavaScript есть красные и синие функции. Красные функции в JavaScript - это асинхронные функции, синие - синхронные функции. И все прослеживается, все та же цепочка… Красные функции вызывать больно в Schlecht!Script, а асинхронные функции вызывать больно в JavaScript.

И внутри синих функций мы не можем писать красные функции. Я еще скажу об этом позже.


Почему это больно? Откуда боль при вызове и при написании асинхронных функций?

У нас по-другому работают условные операторы, циклы, return. У нас не работает try/catch, и асинхронные функции ломают абстракцию.

О каждом пункте немного подробнее.


Вот так выглядит синхронный код, где shouldProcess и process - это функции синхронные, и работают условные операторы, работает for, в общем, все хорошо.

То же самое, но асинхронное, будет выглядеть вот так вот:

Там появилась рекурсия, мы передаем состояние в параметры, в функцию. В общем, смотреть прямо-таки неприятно. У нас не работает try/catch и, я думаю, мы все знаем, что если мы обернем синхронный блок кода в try/catch, исключения мы не поймаем. Нам нужно будет передать callback, перенавесить обработчик событий, в общем, у нас нет try/catch…

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

В общем и целом, говоря об асинхронности в JavaScript, можно сказать, что все там грустно.

Но что мы все об асинхронности? Давайте немного обо мне поговорим, наконец.


Я пришел, чтобы вас всех спасти. Ну, я попробую это сделать.

Меня зовут Андрей, я работаю в стартапе «Productive Mobile» в Берлине. Я помогаю с организацией MoscowJS и я являюсь соведущим RadioJS. Мне очень интересна тема асинхронности и не только в JavaScript, я считаю, что, в принципе, это определяющий момент языка. То, как язык работает с асинхронностью, определяет его успех и то, насколько людям приятно и удобно с ним работать.

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

Множество событий - это, например, событие DOM или подключение к серверу - что-то, что излучает множество нескольких типов событий.

Единичная операция - это, к примеру, чтение из базы. Единичная асинхронная операция возвращает нам либо один результат, либо возвращает ошибку. Больше никаких вариантов нет.

И, говоря об этих двух сценариях, интересно порассуждать: вот, типа, асинхронность - плохо, в общем, все грустно… А что мы на самом деле хотим? Как бы выглядел идеальный асинхронный код?


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

Мы хотим обработки исключений. Зачем нам try/catch, если мы не можем его использовать в асинхронных операциях? Это просто странно.

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

Вот, чего мы хотим.

А что у нас есть сегодня, и какие инструменты у нас появятся в будущем?


Если мы говорим об ECMAScript 6 (это, в принципе, то, о чем я буду говорить сегодня), для работы с множеством событий у нас есть EventEmitter и Stream, а для работы с единичными асинхронными операциями - Continuation Passing Style (они же callback"и), Promises и Coroutines.


В ECMAScript 7 у нас появятся Async Generators для работы с множеством событий и Async/Await - для работы с единичными асинхронными операциями.

Об этом и поговорим.

Начнем с того, что у нас есть в ECMAScript 6 для работы с множеством асинхронных событий. Напомню, например, это обработка событий мыши или нажатий на клавиши. У нас есть паттерн EventEmitter, который реализован в браузере в Node.js. Он встречается практически в любой API, где мы работаем с множеством событий. EventEmitter говорит нам, что мы можем создать объект, который излучает события, и навешивать обработчики на каждый тип события.


Интерфейс очень простой. Мы можем добавлять EventListener, убирать EventListener по названию event"а, передавая туда сallback.


К примеру, в XMLHttpRequest, когда я говорю о множестве событий, я имею в виду, что у нас может быть множество событий progress. Т.е. по мере того, как мы загружаем какие-то данные с помощью AJAX-запроса, нам выстреливают события progress, и по одному разу выстреливают события load, abort и error:


Error - это особенное событие, универсальное событие в EventEmitter"ах и в Stream"ах для того чтобы уведомить пользователя об ошибке.

Есть множество реализаций:


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

Важно сказать, что в Node.js EventEmitter встроен по умолчанию.

Итак, это то, что у нас есть практически по стандарту в API и браузерах в Node.js.

Что у нас еще есть для работы с множеством событий? Stream.

Stream - это поток данных. Что такое данные? Это могут быть бинарные данные, например, данные из файла, текстовые данные, либо объекты или события. Самые популярные примеры:


Есть несколько типов потоков:


Здесь мы рассматриваем цепочку преобразований из Stylus файлов в css файлы, добавляя автопрефиксер, потому что все мы любим Андрея Ситника и его автопрефиксер.

Вы видите, что у нас есть несколько типов потоков - поток-источник это gulp.src, который читает файлы и излучает объекты файлы, которые потом идут в потоки преобразования. Первый поток преобразования делает из stylus файла css, второй поток преобразования добавляет префиксы. И последний тип потоков - это поток-потребитель, который принимает эти объекты, пишет что-то куда-то на диск, и ничего не излучает.


Т.е. у нас есть 3 типа потоков - источник данных, преобразование и потребитель. И эти паттерны прослеживаются везде, не только в gulp, но и при наблюдении за DOM событиями. У нас есть потоки, которые излучают DOM-события, которые их преобразуют и что-то, что потребляя эти DOM-события, возвращает конкретный результат.

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

Есть несколько реализаций потоков, или они же Observables:


В Node.js потоки встроенные - это Node Streams.

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


Когда мы говорим о тех критериях, по которым мы сравниваем асинхронные API, у нас не работают, по большому счету, операторы return, операторы-циклы, у нас не работают try/catch, естественно, и до единого интерфейса с синхронными операциями нам еще далеко.

В общем, для работы с множеством событий в ECMAScript 6 все не очень хорошо.

Когда мы говорим об единичных асинхронных операциях, у нас есть 3 подхода в ECMAScript 6:


Continuation Passing Style, они же - callback"и.


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


Проблемы с этим подходом, я думаю, вы тоже все понимаете.


Вот так бы мы получали ленту твитов пользователей асинхронно, если бы все функции были синхронными.


Тот же самый код, но синхронно, выглядит следующим образом:


Можно увеличить шрифт, чтобы было виднее. И еще немного увеличить… И мы прекрасно понимаем, что это Schlecht!Script.


Я говорил, что они украли мою идею.

Continuation Passing Style - это стандартный API в браузере в Node.js, мы работаем с ними постоянно, но это неудобно. Поэтому у нас есть Promises. Это объект, который представляет собой асинхронную операцию.


Promise - это как бы обещание что-то сделать в будущем, асинхронно.


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

Если мы сравниваем этот подход с Continuation Passing Style, Promises, естественно, удобнее пользоваться - они дают нам возможность писать гораздо меньше бойлерплейта.

Continuation Passing Style, по-прежнему, используется во всех API по умолчанию, в Node.js, в io.js., и они даже не планируют переходы на Promises по нескольким причинам. Сначала многие говорили, что причины - это производительность. И это действительно так, исследования 2013 года показывают, что Promises сильно позади callback"ов. Но с появлением таких библиотек как bluebird, мы уже можем уверенно сказать, что это не так, потому что Promises в bluebird приближаются в производительности к callback"ам. Важный момент: почему Promises не рекомендуют использовать в API до сих пор? Потому что, когда вы выдаете Promises из вашей API, вы навязываете имплементацию.

Все Promises библиотеки должны подчиняться стандарту, но выдавая Promises, вы так же выдаете и имплементацию, т.е. если вы написали свой код, используя медленные Promises, и выдаете медленный Promises из API, это будет не очень приятно пользователям. Поэтому для внешних API, конечно же, по-прежнему рекомендуют использовать callback"и.


Реализаций Promises - масса, и если вы не написали свою реализацию, вы ненастоящий JavaScript-программист. Я не написал свою реализацию Promises, поэтому мне пришлось придумать свой язык.

Итак, Promises, в общем, чуть меньше бойлерплейта, но, тем не менее, все еще не так хорошо.

Что по поводу Coroutines? Здесь уже начинаются интересные штуки. Представьте…

Это интересно. Мы были на JSConf в Будапеште, и там был сумасшедший человек, который на JavaScript программировал квадракоптер и что-то еще, и половину из того, что он пытался нам показать, у него не получалось. Поэтому он постоянно говорил: «OK, теперь представьте… Этот квадракоптер взлетел и все получилось...».

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


Здесь функция получает имя пользователя, она лезет в базу, получает объект пользователя, возвращает его имя. Естественно, «залезть в базу» - функция getUser асинхронная. Что, если мы могли бы поставить функцию getUserName на паузу в момент вызова getUser? Вот, мы выполняем нашу getUserName функцию, дошли до getUser и остановились. getUser сходил в базу, получил объект, вернул его в функцию, мы продолжаем выполнение. Насколько круто это было бы.

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


Это не блокирующая операция. Мы останавливаем выполнение конкретной функции в конкретном месте.


Как getUserName выглядит с помощью генераторов на JavaScript? Нам нужно добавить «*» в объявление функции, чтобы сказать о том, что функция возвращает генератор. Мы можем использовать ключевое слово «yield» в том месте, где мы хотим поставить функцию на паузу. И важно помнить, что getUser здесь возвращает Promises.

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


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

Итого, вот, что у нас получается:


У нас функция, внутри которой мы можем использовать if, for и другие операторы.

Чтобы вернуть значение, мы просто пишем return, так же, как в синхронной функции. Мы можем использовать try/catch внутри, и мы поймаем исключение.


Если Promises с getUser разрешится с ошибкой, это выкинется как исключение.

getUserName функция возвращает Promises, поэтому можем работать с ним так же, как с любым Promises, можем навешивать callback"и с помощью then, чейнить и т.д.

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


Есть множество реализаций. Какие-то используют генераторы, которые уже часть стандарта, есть Fibers, которые в Node.js работают и которые не используют генератор, а свои заморочки у них.

В общем, это третий подход для работы с единичными асинхронными операциями, и это пока еще хак, но мы уже можем использовать код, который приближен к синхронному. Мы можем использовать условные операторы, циклы и блоки try/catch.


Т.е. ECMAScript 6 для работы с единичными асинхронными операциями как бы немного приближает нас к желаемому результату, но по-прежнему проблема единого интерфейса не решена, даже в Coroutines, потому что нам нужно писать «*» специальную и использовать ключевой оператор «yield».


Итак, в ECMAScript 6 для работы с множеством событий у нас есть EventEmitter и Stream, для работы с единичными асинхронными операциями - CPS, Promises, Coroutines. И все это, вроде бы, здорово, но чего-то не хватает. Хочется большего, чего-то отважного, смелого, нового, хочется революции.

И ребята, которые пишут ES7, решили дать нам революцию и принесли для нас Async/Await и Async Generators.


Async/Await - это стандарт, который позволяет нам работать с единичными асинхронными операциями, такими, как, например, запросы в БД.

Вот так мы писали getUserName на генераторах:


А вот так тот же код выглядит с помощью Async/Await:


Все очень похоже, по большому счету, это шаг в сторону от хака к стандарту. Здесь у нас появилось ключевое слово «async», которое говорит о том, что функция асинхронная, и она вернет Promise. Внутри асинхронной функции мы можем использовать ключевое слово «await», там, где мы возвращаем Promise. И мы можем дожидаться выполнения этого Promise, мы можем ставить функцию на паузу и дожидаться выполнения этого Promise.


И так же у нас работают условные операторы, циклы, и try/catch, то бишь, асинхронные функции легализованы в ES7. Теперь мы явно говорим, что если функция асинхронная, то добавьте ключевое слово «async». И это, в принципе, не так плохо, но опять же единого интерфейса у нас нет.

Что по поводу множества событий? Здесь у нас есть стандарт, который называется Async Generators.

Что такое, вообще, множество? Как мы работаем с множеством в JavaScript?


C множеством мы работаем при помощи циклов, так давайте работать с множеством событий при помощи циклов.


Внутри асинхронной функции мы можем использовать ключевую конструкцию «for… on», которая нам позволяет итерировать по асинхронным коллекциям. Как бы.

В данном примере observe возвращает нам что-то, по чему мы можем итерировать, т.е. каждый раз, когда пользователь будет двигать мышкой, у нас будет появляться событие «mousemove». Мы попадаем в этот цикл, и обрабатываем как-то это событие. В данном случае рисуем черточки на экране.


Т.к. функция асинхронная, важно понимать, что она возвращает Promise. Но что, если мы хотим вернуть множество значений, если мы хотим, например, обрабатывать как-то сообщения из веб-сокета, фильтровать их? Т.е. у нас поступает множество и на выходе у нас множество. Здесь нам помогают асинхронные генераторы. Мы пишем «async function *» и говорим о том, что функция асинхронна, и мы возвращаем множество какое-то.


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


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

Вопрос: что возвращает filterWSMessages?


Это точно не Promise, потому что это какая-то коллекция, что-то в этом роде… Но это и не массив.


Даже больше. Что возвращают эти Observe, которые генерят события?

А возвращают они т.н. объекты Observables. Это новое слово, но по большому счету, Observables - это потоки, это Streams. Т.о., круг замыкается.

Итого, у нас есть для работы с асинхронными единичными операциями Async/Await, для работы с множеством - Async Generators.

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

Чтобы получить ленту твитов, в CPS мы писали бы вот такой код:


Много бойлерплейта, обработка ошибок, ручная практически и, в общем, не очень приятная.

С помощью Promise код выглядит таким вот образом:


Бойлерплейт поменьше, мы можем обрабатывать исключения в одном месте, что уже хорошо, но, тем не менее, есть эти then..., не работают ни try/ catch, ни условные операторы.

С помощью Async/Await получаем такую конструкцию:


И примерно то же нам дают Coroutines.

Здесь все шикарно, за исключением того, что нам нужно объявить эту функцию как «async».

Что касается множества событий, если мы говорим о DOM-событиях, вот так мы обрабатывали бы mousemove и рисовали бы по экрану с помощью EventEmitter"а:


Тот же самый код, но с помощью Stream"ов и библиотеки Kefir выглядит таким образом:


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

Async Generators выглядит таким образом:


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

По-моему, это огромный путь.

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

  • Определите вашу задачу, т.е. если вы работаете с множеством событий, имеет смысл посмотреть на Streams или, возможно даже, на Async Generators, если у вас есть транспайлер.
  • Если вы работаете с базой, например, отправляете туда запросы или отправляете AJAX-запросы, которые могут либо зафейлиться, либо выполниться, используйте Promises.
  • Обдумайте ваши ограничения. Если вы можете использовать транспайлер, имеет смысл посмотреть на Async/Await и Async Generators. Если вы пишете API, возможно, не имеет смысла экспоузить Promise в качестве внешней API и делать все на callback’ах.
  • Используйте лучшие практики, помните про события error на потоках и на EventEmitter"ах.
  • Помните про специальные методы вроде Promise.all и т.д.

Я знаю, всех вас интересует судьба Schlecht!Script, когда он будет выложен на GitHub и т.д., но дело в том, что из-за постоянной критики, обвинений в плагиате - говорят, что язык такой уже есть, ничего нового я не изобрел, я решил закрыть проект и посвятить себя, может быть, чему-то полезному, важному, интересному, возможно, я даже напишу свою библиотеку Promises.

Коды (асинхронный и синхронный): формирование и установка

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

Ранее в Google Analytics предлагался стандартный код, который влиял на скорость загрузки страницы и на сбор данных.

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

Асинхронный код – это улучшенный фрагмент кода JavaScript, который загружает код отслеживания ga.js в фоновом режиме, без приостановки загрузки других скриптов и контента на страницах вашего веб-сайта.

Преимущества использования асинхронного кода:

  • Более точный сбор данных о коротких посещениях
  • Если клики произошли до загрузки кода, данные будут сохранены
  • Если у вас установлена стандартная версия кода, рекомендуется обновить код на асинхронный. Для этого необходимо удалить старый фрагмент кода, и на его место встроить асинхронный код. После установки асинхронного кода данные начнут появляться в аккаунте в течение 24 часов.

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

    Формирование и установка кода

    1. Код создается на уровне профиля. Необходимо перейти на вкладку «Администратор».

    3. Полученный код необходимо скопировать и встроить на страницу перед закрывающим тегом .

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

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

    Как вы знаете, общение в ВК не заканчивается перепиской с друзьями. Здесь есть огромное количество групп и сообществ, где можно оставлять комментарии. Да что там группы, когда можно зайти на стену к другу и написать что-нибудь?

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

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

    Что можно сделать? Мы можем лишь предложить вам посмотреть на ваши же комментарии, к которым были оставлены ответы или поставлены сердечки (лайки). Сделать это можно вот каким образом.

    Зайдите на свою страницу и в меню нажмите «Мои ответы».

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

    Если вы хотите увидеть только те комментарии, на которые были даны ответы, нажмите на кнопку «Ответы».

    Да, это не самый оптимальный вариант для поиска своих комментариев, но на текущий момент другого выхода из ситуации нет. К тому же ответы на комментарии сохраняются долго. Нам, к примеру, удалось найти комментарий, оставленный 9 месяцев назад.