Можно ли писать "настоящие" асинхронные функции в node.js

Я пытался понять, как ключевые слова и обещания 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 является однопоточным, и lowLevelFileReading блокирует выполнение до его завершения. Вы можете изучить Workers, если у вас действительно дорогостоящая в вычислительном отношении задача.

Emissary 04.04.2021 11:30
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
1
1
41
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Краткое заявление об отказе от ответственности: я только что прочитал это и могу немного неправильно объяснить.

Проблема в том, что Node.js обычно работает в однопоточном режиме. Но при выполнении какой-либо операции, не связанной с javascript, он может «передать» ее на аутсорсинг и заставить ее работать параллельно на ядре. Но когда у вас есть такая функция, как lowLevelFileRead, в вашем случае, которая не запускает никаких операций ввода-вывода, она будет блокировать выполнение другого кода.

Вот статья, которую я нашел, которая может помочь объяснить вещи:

https://medium.com/@mohllal/node-js-multithreading-a5cd74958a67

В вашей версии кода быстрое обещание по-прежнему не запускается до завершения lowLevelFileReading ().

Yusuf K 04.04.2021 11:25

Это не решает проблему медленной функции lowLevelFileReading и блокировка, она просто добавляет задержку после того, как эта медленная, блокирующая функция будет запущена перед выполнением обещания.

Quentin 04.04.2021 11:28

«Если поместить его в тайм-аут, он будет работать асинхронно». - Нет, это не так. Он просто запускает его через 3 секунды. Он по-прежнему медленный и блокирующий. Другой материал может запускать перед, но не одновременно с ним.

Quentin 04.04.2021 11:34

Но быстрое обещание начинается до операции чтения

MrCodingB 04.04.2021 11:35

Дело не в том, чтобы сначала выполнить быстрое обещание, дело в том, что lowLevelFileReading блокирует все остальное пока, которое он выполняет, независимо от того, когда это может быть.

Quentin 04.04.2021 11:36

Хм ... я еще посмотрю

MrCodingB 04.04.2021 11:37

Снова отредактировал свой ответ

MrCodingB 04.04.2021 12:02

Другие вопросы по теме