Рубрики
Без рубрики

Веб-работники в действии: почему они полезны и как вы должны их использовать

Голодными мозговыми веб-работниками в действии: почему они полезны, и как вы должны использовать ихфото на Fabian Grohs на UnsplashJavascript – это одно резьбовые, а несколько сценариев не могут выполняться одновременно. Так что, если мы выполняем любые тяжелые вычисления задачи, то иногда наша страница становится не реагировательной

Автор оригинала: FreeCodeCamp Community Member.

Голодный мозг

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

Например:

average = (numbers) => {
    let startTime = new Date().getTime();
    let len = numbers,
        sum = 0,
        i;

    if (len === 0) {
        return 0;
    }

    for (i = 0; i < len; i++) {
        console.log('i :: ', i)
        sum += i;
    }

    let endTime = new Date().getTime();
    alert('Average - ', sum / len);
}

hello = () => {
    alert("Hello World !!");
}

/*
Paste the above code in browser dev tool console
and try to call average(10000) and hello one by one
*/

В приведенном выше примере, если вы звоните средний до Привет Метод, то ваша страница станет не отвечает, и вы не сможете нажать на Привет до исполнения средний завершено.

Вы можете увидеть, что когда средний Сначала называется 10000 в качестве ввода, он занял ~ 1,82 секунды. Для этого времени страница становится не реагированной, и вы не смогли нажать на кнопку Hello.

Асинхронное программирование

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

Хороший пример Async Programming – XHR запрос В этом мы ударили API асинхронно и в ожидании ответа, другой код может быть выполнен. Но это ограничено определенным случаям использования, связанные с Web API в основном.

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

Например:

average = (numbers) => {
    let startTime = new Date().getTime();
    var len = numbers,
        sum = 0,
        i;

    if (len === 0) {
        return 0;
    }

    let calculateSumAsync = (i) => {
        if (i < len) {
            // Put the next function call on the event loop.
            setTimeout(() => {
                sum += i;
                calculateSumAsync(i + 1);
            }, 0);
        } else {
            // The end of the array is reached so we're invoking the alert.
            let endTime = new Date().getTime();
            alert('Average - ', sum / len);
        }
    };

    calculateSumAsync(0);
};

hello = () => {
    alert('Hello World !!')
};

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

Здесь, для того же входа 10000, он занял ~ 60 секунд, что очень неэффективно.

Итак, как мы решаем эти виды вопросов эффективно?

Ответ – Веб-работники.

Что такое веб-работники?

Web-работники в JavaScript – отличный способ выполнить некоторую задачу, которая очень трудонаправлена, и время, принимая в ните отдельно от основной нити. Они работают в фоновом режиме и выполняют задачи, не мешающие пользовательскому интерфейсу.

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

Web-работники создаются функцией конструктора Работник () который запускает именованный файл JS.

// create a dedicated web worker
const myWorker = new Worker('worker.js');

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

Мы узнаем больше о создании и работе веб-работников в следующем разделе.

Рабочий поток имеет свой собственный контекст и, следовательно, вы можете получить доступ к выбранным функциям внутри рабочей нити, как – веб-розетки, индексированные БД.

Есть некоторые Ограничения с веб-работниками –

  1. Вы не можете напрямую манипулировать домом изнутри рабочего.
  2. Вы не можете использовать некоторые методы по умолчанию и свойства объекта окна, поскольку Object Object недоступен внутри рабочей нити.
  3. Контекст внутри рабочей нити можно получить доступ через Выделенный рабочийЛобальсcope или SharedWorkergLobalscope в зависимости от использования.

Особенности веб-работников

Есть два типа веб-работников –

  1. Выделенный веб-работник – Выделенный работник доступен только скриптом, который назвал его.
  2. Общий веб-работник – Общий работник доступен несколькими сценариями – даже если они обращаются к разным окнам, IFRAMES или даже работникам.

Давайте обсудим больше о тех двух типах веб-работников –

Создание веб-работника

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

Выделенный веб-работник

  • Создание нового работника прост, просто позвоните рабочему конструктору и пропустите путь скрипта, который вы хотите выполнить в качестве работника.
// create a dedicated web worker
const myWorker = new Worker('worker.js');

Общий веб-работник:

  • Создание нового общего работника в значительной степени так же, как у специализированного работника, но с другим именем конструктора.
// creating a shared web worker
const mySharedWorker = new SharedWorker('worker.js');

Связь между основной и рабочей нитью

Связь между основной нитью и рабочей нитью происходит через PostMessage Метод и OnMessage обработчик события.

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

(() => {
  // new worker
  let myWorker = new Worker('worker.js');

  // event handler to recieve message from worker
  myWorker.onmessage = (e) => {
    document.getElementById('time').innerHTML = `${e.data.time} seconds`;
  };

  let average = (numbers) => {
    // sending message to web worker with an argument
    myWorker.postMessage(numbers);
  }

  average(1000);
})();

А внутри веб-работника вы можете ответить, когда сообщение получено путем записи блока обработчика событий, как это:

onmessage = (e) => {
    let numbers = e.data;
    let startTime = new Date().getTime();
    let len = numbers,
        sum = 0,
        i;

    if (len === 0) {
        return 0;
    }

    for (i = 0; i < len; i++) {
        sum += i;
    }

    let endTime = new Date().getTime();
    postMessage({average: sum / len, time: ((endTime - startTime) / 1000)})
};

OnMessage Обработчик позволяет запустить какойкий раз, когда сообщение получено сообщение.

Здесь мы рассчитываем средние числа, а затем используйте PostMessage () Опять же, чтобы опубликовать результат обратно в основную нить.

Как вы можете видеть на Линия 6 в main.js Мы использовали событие OnMessage на экземпляре работника. Так что всякий раз, когда рабочие потоки используют PostMessage, OnMessage в основном потоке запущено.

  • Общий веб-работник В случае общего веб-работника система связи немного отличается. В качестве одного работника разделяется между несколькими сценариями, нам нужно общаться через объект портов работника. Это делается неявно в случае преданных работников. Вам необходимо использовать метод PostMessage, когда вы хотите отправить сообщение рабочему.
(() => {
  // new worker
  let myWorker = new Worker('worker.js');

  // event handler to recieve message from worker
  myWorker.onmessage = (e) => {
    document.getElementById('time').innerHTML = `${e.data.time} seconds`;
  };

  let average = (numbers) => {
    // sending message to web worker with an argument
    myWorker.postMessage(numbers);
  }

  average(1000);

Внутри веб-работника ( Main-Shared-Working.js ) Это немного сложна. Во-первых, мы используем Onconnect Обработчик для пожара, когда происходит подключение к порту ( Линия 2 ). Мы используем Порты Атрибут этого объекта события, чтобы схватить порт и хранить его в переменной ( Линия 4 ). Далее мы добавляем сообщение Обработчик на порту выполнять расчет и вернуть результат к основной нити ( Линия 7 и строка 25 ) Как это:

onmessage = (e) => {
    let numbers = e.data;
    let startTime = new Date().getTime();
    let len = numbers,
        sum = 0,
        i;

    if (len === 0) {
        return 0;
    }

    for (i = 0; i < len; i++) {
        sum += i;
    }

    let endTime = new Date().getTime();
    postMessage({average: sum / len, time: ((endTime - startTime) / 1000)})
};

Прекращение веб-работника

Если вам нужно немедленно прекратить рабочий работник от основного потока, вы можете сделать это, позвонив на работу работника прекратить Метод:

// terminating a web worker instance
myWorker.terminate();

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

Нерест веб-работника

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

Импорт сценариев

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

importScripts();                         /* imports nothing */
importScripts('foo.js');                 /* imports just "foo.js" */
importScripts('foo.js', 'bar.js');       /* imports two scripts */
importScripts('//example.com/hello.js'); /* You can import scripts from other origins */

Рабочая демо

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

Здесь вы увидите 3 раздела:

  1. Блокирующий код .: Когда вы нажимаете на Рассчитать среднее , погрузчик не отображается и через некоторое время вы видите окончательный результат и принятый во время. Это потому, что как только Средний метод вызывается, я вызвал Showloader Метод также. Но поскольку js – это одиночная резьба, он не будет выполнен Showloader до тех пор, пока выполнение среднего выполняется. Итак, вы не сможете увидеть загрузчик в этом случае.
  2. ASYNC код : В этом я попытался достичь ту же функциональности, используя метод SettimeOut и поместив все выполнение функции в контур событий. Вы увидите загрузчик в этом случае, но ответ требует времени по сравнению с методом, определенным выше.
  3. Веб-пользователь : Это пример использования веб-работника. В этом вы увидите загрузчик, как только вы нажимаете на вычисление среднего, и вы получите ответ одновременно с методом 1, для того же номера.

Вы можете получить доступ к исходному коду для того же здесь Отказ

Расширенные концепции

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

  1. Политика безопасности содержимого – У веб-работников есть свой собственный контекст исполнения, независимый от документа, который их создал, и из-за этой причины они не регулируются политикой безопасности содержания родительской нити/работника. Исключением из этого является если происхождение рабочего сценария является глобально уникальным идентификатором (например, если его URL имеет схему данных или BLOB). В этом случае работник наследует политику безопасности содержания документа или работника, созданного его.
  2. Передача данных на работников и от работников – Данные, переданные между основным и рабочим потоком, является скопирован И не поделился. Объекты сериализуются, поскольку они передаются рабочему, и впоследствии десериализовались на другом конце. Страница и работника Не разделяйте тот же экземпляр поэтому конечный результат в том, что дубликат создается на каждом конце. Браузеры реализованы Структурированные клонирование алгоритм для достижения этого.
  3. Встроенные работники – Вы также можете встроить код работника внутри веб-страницы (HTML). Для этого вам нужно добавить тег скрипта без атрибута SRC и назначить его неизаятельным типом MIME, например:




  
  embedded worker
  
  


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

[Ссылки]

GitHub Repo: https://github.com/bhushangoel/webworker-demo-1 Веб-документ в действии: https://bhushangoel.github.io/webworker-demo-1/ JS Demo Showcase: https://bhushangoel.github.io/

Спасибо за чтение.

Счастливое обучение:)

Первоначально опубликовано www.thehungrybrain.com .