Я пытался понять, как ключевые слова и обещания async / await работают в NodeJs. Ниже мой тестовый код:
function lowLevelFileReading() {
for (let i = 0; i < 100000; i++) {
for (j = 0; j < 100000; j++) {
let lol = 5;
lol = lol * lol + 2;
}
}
}
function slowPromise() {
return new Promise(resolve => {
setTimeout(() => {
console.info("starting slow promise " + new Date())
lowLevelFileReading();
resolve("slow");
console.info("slow promise is done " + new Date())
}, 1000);
})
}
function fastPromise() {
return new Promise(resolve => {
setTimeout(() => {
console.info("starting fast promise" + new Date())
resolve("fast")
console.info("fast promise is done" + new Date())
}, 3000);
})
}
async function parallel() {
// Start 2 "jobs" in parallel and wait for both of them to complete
await Promise.all([
(async()=>console.info(await slowPromise()))(),
(async()=>console.info(await fastPromise()))()
])
}
parallel();
И вот мой вывод на консоль:
starting slow promise Sun Apr 04 2021 10:41:30 GMT+0300 (GMT+03:00)
slow promise is done Sun Apr 04 2021 10:41:54 GMT+0300 (GMT+03:00)
slow
starting fast promiseSun Apr 04 2021 10:41:54 GMT+0300 (GMT+03:00)
fast promise is doneSun Apr 04 2021 10:41:54 GMT+0300 (GMT+03:00)
fast
На моем компьютере lowLevelFileReading() выполняется примерно за 25 секунд, поэтому я думаю, что он подходит для тестирования какой-нибудь длительной операции.
Как видно из приведенного выше, код в slowPromise() настроен на запуск через 1 секунду, а код в fastPromise() настроен на запуск через 3 секунды.
Я ожидаю, что быстрое обещание начнется через 2 секунды после медленного обещания. Но этого не происходит. В выводе консоли вы можете видеть, что быстрое обещание не запускается, пока не будет выполнено медленное обещание. Пожалуйста, посмотрите временные метки журналов консоли.
Я думаю, что сделать то, что я пытаюсь сделать, в javascript невозможно. Но тогда я не понимаю, как работает функция чтения асинхронных файлов в библиотеке fs. Я имею в виду, чем отличается реализация fs.readFile() от моей воображаемой реализации lowLevelFileReading(). Разве узел по-разному относится к некоторым "особым" методам?
Я не могу себе представить, как можно реализовать сервер node.js, используемый в качестве бэкэнда для веб-сайта с миллионами пользователей с трудоемкими операциями. Не могли бы вы поделиться некоторыми соображениями?



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Краткое заявление об отказе от ответственности: я только что прочитал это и могу немного неправильно объяснить.
Проблема в том, что Node.js обычно работает в однопоточном режиме. Но при выполнении какой-либо операции, не связанной с javascript, он может «передать» ее на аутсорсинг и заставить ее работать параллельно на ядре. Но когда у вас есть такая функция, как lowLevelFileRead, в вашем случае, которая не запускает никаких операций ввода-вывода, она будет блокировать выполнение другого кода.
Вот статья, которую я нашел, которая может помочь объяснить вещи:
https://medium.com/@mohllal/node-js-multithreading-a5cd74958a67
В вашей версии кода быстрое обещание по-прежнему не запускается до завершения lowLevelFileReading ().
Это не решает проблему медленной функции lowLevelFileReading и блокировка, она просто добавляет задержку после того, как эта медленная, блокирующая функция будет запущена перед выполнением обещания.
«Если поместить его в тайм-аут, он будет работать асинхронно». - Нет, это не так. Он просто запускает его через 3 секунды. Он по-прежнему медленный и блокирующий. Другой материал может запускать перед, но не одновременно с ним.
Но быстрое обещание начинается до операции чтения
Дело не в том, чтобы сначала выполнить быстрое обещание, дело в том, что lowLevelFileReading блокирует все остальное пока, которое он выполняет, независимо от того, когда это может быть.
Хм ... я еще посмотрю
Снова отредактировал свой ответ
Можно сказать, что обещания выполняются одновременно, а не параллельно. Javascript является однопоточным, и
lowLevelFileReadingблокирует выполнение до его завершения. Вы можете изучитьWorkers, если у вас действительно дорогостоящая в вычислительном отношении задача.