Рассматривая ваши примеры, вы, похоже, рассматриваете асинхронное выполнение как параллельное выполнение, поскольку ожидаете, что код в основном потоке будет выполняться, пока бесконечный цикл выполняется в другом потоке.Параллельное выполнение - это форма асинхронной операции, но в javascript мы обычно используем параллельное выполнение.
Но что на самом деле означает синхронизация, асинхронная, параллельная, одновременная работа?
Синхронный код - самый простой в работес, потому что это дает лучшие гарантии:
/* 1 */ doWorkSync(() => console.log("callback"));
/* 2 */ console.log("after doWorkSync");
В приведенном выше коде, где doWorkSync
- синхронная функция, мы знаем, что функция обратного вызова будет выполняться перед строкой 2.
Параллельный код, который вjavascript, обычно называемый async, дает нам немного худшую гарантию:
/* 1 */ doWorkAsync(() => console.log("callback"));
/* 2 */ console.log("after doWorkAsync");
В приведенном выше коде мы гарантируем, что функция обратного вызова будет вызвана после полного выполнения текущего синхронного кода, то есть после строки 2. Но мы не делаемточно знать когда.Он может быть вызван немедленно, но может быть вызван намного позже.
Но наиболее сложный код для работы - это параллельный код:
/* 1 */ doWorkParallel(() => console.log("callback"));
/* 2 */ console.log("after doWorkParallel");
В приведенном выше коде у нас нет никаких гарантий.Код обратного вызова может быть запущен перед строкой 2, одновременно или позже.Поэтому код должен быть написан так, чтобы он был подготовлен для любой из этих ситуаций.
Самый простой способ написать асинхронную (параллельную) функцию в JavaScript - это использовать Promise
:
console.log("first");
Promise.resolve().then(() => console.log("last"));
console.log("second");
В приведенном выше коде then
обратный вызов выполняется сразу после того, как текущий синхронный код запускается из очереди микрозадач.
Параллельный код может быть выполнен вJavaScript с Worker
s:
function parallel() {
function work() {
block(200); // message from the main thread is logged while this blocks the worker
console.log("second"); // logs from the worker can be seen in the browser console
function block(time) {
const startDate = Date.now();
while (startDate + time > Date.now()) {};
}
}
new Worker(window.URL.createObjectURL(new Blob([`(${work})()`]), {
type: 'application/javascript'
}));
}
function block(time) {
const startDate = Date.now();
while (startDate + time > Date.now()) {}
}
parallel();
// timeout is needed because blob response is handled on the main thread
setTimeout(() => {
console.log("first");
block(500); // message from parallel is logged while this blocks the main thread
console.log("last");
}, 100)