Параллелизм

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

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

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

Синхронизация

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

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

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

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

Путь JavaScript касинхронному программированию

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

Цикл событий

Хотя JavaScript является однопоточным языком программирования, среда выполнения JavaScript, такая как движок браузера и Node.js, не является однопоточной. Все они имеют модель параллелизма, основанную на цикле событий. Допустим, поток, который среда выполнения использует для выполнения вашего кода JavaScript, называется основным потоком. Он может попросить другие потоки выполнить некоторые задачи асинхронно, такие как отправка HTTP-запроса, рендеринг пользовательского интерфейса и т. д. Он отправляет запросы задач и ожидает, что другие потоки обработают запросы, но никогда не знает, когда он сможет получить ответы от них, поскольку система работает асинхронно. Итак, как мы можем убедиться, что результат вычислений используется правильно? Есть два вопроса, которые нужно решить — что делать и когда с этим делать. Используя функции обратного вызова, мы можем сообщить системе, что должно произойти, когда асинхронная операция завершится успешно/неудачно. Используя цикл обработки событий, мы можем сказать, когда выполнять эти функции обратного вызова с доступными асинхронными результатами. По сути, цикл событий, который использует среда выполнения JavaScript, на самом деле инкапсулирует функции обратного вызова из разных потоков в некоторые задачи и помещает их в очередь сообщений, когда основной поток свободен, он будет брать задачи из очереди одну за другой для обработки. их. На самом деле все эти асинхронные задачи используют очередь сообщений для уведомления основного потока о том, что эти задания выполнены, а основной поток использует очередь сообщений для обработки ответов. Вся система управляется событиями, поэтому цикл выполнения задач называется циклом событий.

Перезвонить

«Обратный вызов» — это решение для асинхронного программирования на JavaScript, но оно не очень удобно для разработчиков. «Ад обратных вызовов» — это некоторый код, с которым вы, вероятно, столкнетесь, когда сложность асинхронной логики возрастет из-за вложенной природы обратных вызовов.

Обещать

Термин обещание впервые был предложен в статьеr Влияние прикладного программирования на многопроцессорную обработку в 1976 году и формализован в статье 1988 года под названием Промисы: лингвистическая поддержка эффективного асинхронного программирования. Вызовы процедур в распределенных системах». Существует много похожих понятий, таких как "возможный", "будущий", "задержка" или "отложенный". Вы можете думать о Promise как об инкапсуляции результата асинхронного вызова. В основном это служит двум целям: 1. У меня еще нет окончательного результата, но я обещаю вам, что вы получите результат в будущем. 2. Если вы хотите что-то сделать с моим будущим результатом, просто скажите мне. Promise значительно улучшил читаемость асинхронного кода по сравнению с обратными вызовами. Для получения дополнительной информации о том, как его использовать, обратитесь к https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Using_promises.

Асинхронно/ждите

Async/await — это еще один синтаксический сахар в асинхронном программировании JavaScript, в котором под капотом используются промисы. Он еще более удобен для разработчиков, поскольку имеет более традиционный синтаксис JavaScript. Для получения дополнительной информации о том, как его использовать, обратитесь к https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Asynchronous/Async_await.

Ссылки:







  • Профессиональный JavaScript для веб-разработчиков, 4-е издание
  • Распределенные вычисления: основы, моделирование и дополнительные темы