Q: Вы понимаете асинхронное программирование, процесс, один поток, многопоток?

JavaScript Ajax CSS ECMAScript 6

Связанные определения

Язык Javascript делит режимы выполнения задач на два типа: синхронный и асинхронный.

  1. Синхронизировать: Когда процесс выполняет запрос, если для возврата информации требуется некоторое время, процесс будет ждать, пока не получит возвращаемую информацию, прежде чем продолжить выполнение.
  2. асинхронный: процесс не должен ждать вечно, а продолжает выполнять следующие операции независимо от состояния других процессов. Когда сообщение возвращается, система уведомляет процесс о его обработке, что может повысить эффективность выполнения.
  3. процесс: В узком смысле экземпляр работающей программы. В широком смысле процесс — это работающая программа с определенной независимой функцией на наборе данных. Это основная единица динамического выполнения операционной системы.В традиционной операционной системе процесс является не только основной единицей распределения, но и основной единицей выполнения.
  4. нить: поток — это один последовательный поток управления в программе.процессОтносительно независимый и планируемый исполнительный блок в системе является базовым блоком, позволяющим системе независимо планировать и назначать ЦП. Относится к единице планирования работающей программы.
  5. один поток: Когда один поток выполняет программу, пути программы, которые он использует, расположены в последовательном порядке.Первый должен быть хорошо обработан, а второй будет выполнен. Однопоточный означает, что в процессе присутствует только один поток.
  6. Многопоточность: Запуск нескольких потоков для одновременного выполнения различной работы в одной программе называется многопоточностью.

Точка знаний

js является однопоточным

JS запускается в браузере и является однопоточным.Каждое окно имеет поток JS.Поскольку он однопоточный, в определенный момент может выполняться только определенный код, а другие коды могут быть заблокированы. Браузеры управляются событиями,браузерМногие модели поведенияасинхронныйДа, события создаются и помещаются в очередь выполнения, движок JavaScript — это однопоточная очередь задач, которая его обрабатывает. Когда происходит асинхронное событие, происходит событие щелчка мыши, происходит событие триггера таймера, триггеры обратного вызова завершения XMLHttpRequest и т. д., помещайте их в очередь выполнения и ждите завершения выполнения текущего кода.

Браузеры не являются однопоточными

Хотя JS запускается в браузере и является однопоточным, браузер не является однопоточным.Например, движок Webkit может иметь следующие потоки:

  • Поток движка JavaScript
  • Поток рендеринга пользовательского интерфейса
  • Поток триггера события браузера
  • поток HTTP-запросов

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

Почему JavaScript является однопоточным, но позволяет AJAX отправлять и вызывать запросы асинхронно, и почему setTimeout также кажется многопоточным?

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

setTimeout(func, 0)Где магия? Это означает, что js-движок должен поместить функцию в очередь основных событий через 0 мс и дождаться выполнения текущего кода перед его выполнением.Примечание: суть в том, чтобы изменить поток кода и поставить выполнение функции в основная очередь событий. Это волшебство этого. Он имеет три применения:

  1. Позвольте браузеру отображать текущие изменения (многие рендеринг пользовательского интерфейса браузера и выполнение js помещаются в поток, блокировка потока приведет к тому, что интерфейс не будет обновляться и отображаться)
  2. Пересчитать время работы скрипта, то есть переоценить предупреждение "скрипт выполняется слишком долго"
  3. Изменен порядок выполнения

Подробное объяснение см. в следующей статье «Умелое использование setTimeout(func, 0)». (Примечание от 2017-11-30: Изначально хотел написать, но случайно наткнулся на статью«На этот раз досконально изучите механизм выполнения JavaScript»Я думаю, что это было написано очень хорошо, так что мне это понравится (#^.^#))

Три метода асинхронного программирования

Один: функция обратного вызова

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

 f1();
 f2();

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

 function f1(callback){
    setTimeout(function () {
      // f1的任务代码
      callback();
    }, 1000);
  }

Код выполнения становится следующим: ​

 f1(f2);

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

2. Мониторинг событий

Другая идея заключается в использовании модели, управляемой событиями. Выполнение задач зависит не от порядка кода, а от того, происходит ли событие.
Возьмите f1 и f2 в качестве примера. Во-первых, привяжите событие к f1 (здесь используется способ написания jQuery).

  f1.on('done', f2);

Приведенная выше строка кода означает, что когда в f1 происходит событие done, выполняется f2. Затем перепишите f1:

  function f1(){
    setTimeout(function () {
      // f1的任务代码
      f1.trigger('done');
    }, 1000);
  }

f1.trigger('done') означает, что после завершения выполнения немедленно запускается событие done, таким образом, начинается выполнение f2.
Преимущество этого метода в том, что его легче понять, можно связать несколько событий, и каждое событие можноУкажите несколько функций обратного вызова, и может«Развязка», что способствует реализации модуляризации. Недостатком является то, что вся программа должна статьуправляемый событиями, процесс операции станет очень неясным.

3. Обещает объект

Промисы — это решение для асинхронного программирования, которое является более разумным и мощным, чем традиционные решения «обратные вызовы» и «события». Впервые он был предложен и реализован сообществом, ES6 вписал его в стандарт языка, унифицированное использование и изначально предоставил объекты Promise. Обещания предоставляют унифицированный API, и различные асинхронные операции могут обрабатываться одинаково.
Основное использование заключается в следующем:

    const promise = new Promise(function(resolve, reject) {
      // ... some code
      if (/* 异步操作成功 */){
        resolve(value);
      } else {
        reject(error);
      }
    });
    promise.then(function(value) {
    // success
    }, function(error) {
     // failure
    });

Другой способ записи сбоев асинхронных операций и перехвата исключений указан ниже.

const promise = new Promise(function(resolve, reject) {
  reject(new Error('test'));
});
promise.catch(function(error) {
  console.log(error);
});

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