Связанные определения
Язык Javascript делит режимы выполнения задач на два типа: синхронный и асинхронный.
- Синхронизировать: Когда процесс выполняет запрос, если для возврата информации требуется некоторое время, процесс будет ждать, пока не получит возвращаемую информацию, прежде чем продолжить выполнение.
- асинхронный: процесс не должен ждать вечно, а продолжает выполнять следующие операции независимо от состояния других процессов. Когда сообщение возвращается, система уведомляет процесс о его обработке, что может повысить эффективность выполнения.
- процесс: В узком смысле экземпляр работающей программы. В широком смысле процесс — это работающая программа с определенной независимой функцией на наборе данных. Это основная единица динамического выполнения операционной системы.В традиционной операционной системе процесс является не только основной единицей распределения, но и основной единицей выполнения.
- нить: поток — это один последовательный поток управления в программе.процессОтносительно независимый и планируемый исполнительный блок в системе является базовым блоком, позволяющим системе независимо планировать и назначать ЦП. Относится к единице планирования работающей программы.
- один поток: Когда один поток выполняет программу, пути программы, которые он использует, расположены в последовательном порядке.Первый должен быть хорошо обработан, а второй будет выполнен. Однопоточный означает, что в процессе присутствует только один поток.
- Многопоточность: Запуск нескольких потоков для одновременного выполнения различной работы в одной программе называется многопоточностью.
Точка знаний
js является однопоточным
JS запускается в браузере и является однопоточным.Каждое окно имеет поток JS.Поскольку он однопоточный, в определенный момент может выполняться только определенный код, а другие коды могут быть заблокированы. Браузеры управляются событиями,браузерМногие модели поведенияасинхронныйДа, события создаются и помещаются в очередь выполнения, движок JavaScript — это однопоточная очередь задач, которая его обрабатывает. Когда происходит асинхронное событие, происходит событие щелчка мыши, происходит событие триггера таймера, триггеры обратного вызова завершения XMLHttpRequest и т. д., помещайте их в очередь выполнения и ждите завершения выполнения текущего кода.
Браузеры не являются однопоточными
Хотя JS запускается в браузере и является однопоточным, браузер не является однопоточным.Например, движок Webkit может иметь следующие потоки:
- Поток движка JavaScript
- Поток рендеринга пользовательского интерфейса
- Поток триггера события браузера
- поток HTTP-запросов
Когда происходит асинхронное событие, оно попадает в очередь событий. Браузер имеет внутренний большой цикл обработки сообщений, цикл событий, который опрашивает очередь событий и обрабатывает события. Например, браузер в данный момент занят обработкой события onclick, когда происходит событие window onSize, асинхронное событие помещается в очередь событий для обработки, и это событие будет выполнено только тогда, когда предыдущая обработка будет завершена и простаивает.
Почему JavaScript является однопоточным, но позволяет AJAX отправлять и вызывать запросы асинхронно, и почему setTimeout также кажется многопоточным?
Запросы Ajax действительно асинхронны, этот запрос выполняетсяБраузер открыл новый потокЗапросы и обратные вызовы событий помещаются в однопоточную очередь событий цикла событий для обработки. Задачи удаления из очереди обрабатываются, когда браузер бездействует, движок JavaScript всегда является однопоточным для запуска функции обратного вызова и однопоточным для обработки своей очереди задач.
setTimeout(func, 0)
Где магия? Это означает, что js-движок должен поместить функцию в очередь основных событий через 0 мс и дождаться выполнения текущего кода перед его выполнением.Примечание: суть в том, чтобы изменить поток кода и поставить выполнение функции в основная очередь событий. Это волшебство этого. Он имеет три применения:
- Позвольте браузеру отображать текущие изменения (многие рендеринг пользовательского интерфейса браузера и выполнение js помещаются в поток, блокировка потока приведет к тому, что интерфейс не будет обновляться и отображаться)
- Пересчитать время работы скрипта, то есть переоценить предупреждение "скрипт выполняется слишком долго"
- Изменен порядок выполнения
Подробное объяснение см. в следующей статье «Умелое использование 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);
});
Преимущество этого в том, что функция обратного вызова становитсяЦепное письмо, ход программы можно четко увидеть, и можно реализовать множество мощных функций.
Например, указание нескольких функций обратного вызова и т. д.