Javascript-форум (https://javascript.ru/forum/)
-   Node.JS (https://javascript.ru/forum/node-js-io-js/)
-   -   Как работает асинхронность? (https://javascript.ru/forum/node-js-io-js/72775-kak-rabotaet-asinkhronnost.html)

vitalyas 25.02.2018 12:10

Как работает асинхронность?
 
Приветствую всех кто просматривает эту тему!
Разъясните пожалуйста следующую ситуацию: да юзера, с разных компов открывают одновременно страницу сайта на ноде, они получат ее одновременно? то есть второй юзер не будет ждать пока, первый получит страницу?
По идее не должен, но почему если для одного юзера есть цикл, то второй ждет пока цикл для первого отработает, хотя для второго нет цикла?
Ведь есть такие ситуации когда на странице нужно вывести в цикле какие то данные для конкретно юзера.
Знаю что это все решается, но как? Где можно почитать, разобраться?Направьте в нужное русло.
Вот мой код:
router.post('/authenticate', function(req, res) {
    User.findOne({email: req.body.email, password: req.body.password}, function(err, user) {
        if (err) {
            res.json({
                type: false,
                data: "Error occured: " + err
            });
        } else {
            if (user) {
                if(user._id == '5a924c98fa27cb2520e56e7d') {

                    for(;;) {

                    }
                }

                console.log('ok1');
                user.setTolken();
                user.token = jwt.sign({
                    email: user.email,
                    password: user.password,
                    id: user._id,
                    time: new Date().getMilliseconds()
                }, process.env.JWT_SECRET, {
                    expiresIn: 60, // 1 week
                    algorithm: 'HS256'
                });
                user.save(function(err, user1) {
                    res.json({
                        type: true,
                        data: user1,
                        token: user1.token
                    });
                });

                console.log('ok5');
                res.json({
                    type: true,
                    data: user,
                    token: user.token
                });

            } else {
                res.json({
                    type: false,
                    data: "Incorrect email/password"
                });
            }
        }
    });
});


Как видно в коде есть бесконечный цикл который блокирует все, для всех юзеров, хотя условие стоит блокировка только для конкретного айдишника

Nexus 25.02.2018 12:20

А не знаю, как это будет работать на ноде, но в браузере этот js ничего не заблокирует, но загрузит процессор на 100%.
Если node также работает, то ничего удивительного в том, что ваш сервер не отвечает.

Зачем так сношать машину?

vitalyas 25.02.2018 12:36

Дело в том, что если делать все то же на пхп, то второй юзер получит ответ и не будет ждать пока цикл выполнится для первого.
В данном коде просто проверка как работает nodejs, так сказать первые шаги, метод проб. nodejs изучаю первую неделю, после нескольких лет разработки на php. Поскольку nodjs однопоточный, то этот цикл лочит и второй юзер ждет первого. Как этого избежать? Процесс блокирует только цикл или без цикла тоже один юзер ждет другого?

Белый шум 25.02.2018 13:21

Цитата:

Сообщение от vitalyas
Дело в том, что если делать все то же на пхп, то второй юзер получит ответ и не будет ждать пока цикл выполнится для первого.

Только потому, что в пхп апач создаст отдельный процесс (или thread) для второго запроса. А если вы возьмёте ReactPHP, то там будет то же самое (и то и другое - однопоточное, хоть и асинхронное). Поэтому я и не стал даже смотреть на все эти новомодные штуки - слишком они критичны к ошибкам подвешивания всех клиентов (и, наверное, к утечкам памяти). Хотя при правильном использовании, конечно, они помогут выжать максимум пользы из процессора.

Избежать - не использовать долгих циклов и использовать асинхронность по максимуму.

Белый шум 25.02.2018 13:26

Цитата:

Сообщение от Nexus
А не знаю, как это будет работать на ноде, но в браузере этот js ничего не заблокирует,

Тоже заблокирует
alert('go');
for(;;){}
alert('end');

vitalyas 25.02.2018 13:33

В итоге получается, что обычный console.log(), при запросе двумя юзерами выполнится последовательно в одном процессе, сначала для первого, потом для второго, а не параллельно, как в двух одновременных процессах пхп?

vitalyas 25.02.2018 13:36

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

Nexus 25.02.2018 13:58

Цитата:

Сообщение от Белый шум
Тоже заблокирует

Я видимо неправильно выразился.
Хотел сказать, что если процесс на 100% грузит CPU, то ничего удивительного в том, что другие пользователи в это время не могут получить ответ от машины нет.

Заставить машину ожидать какое-то время (видимо бесконечное) путем запуска бесконечного цикла - как минимум глупость, тем более в php.

Не знаком с nodejs и желания знакомиться нет, но я сильно сомневаюсь, что все запросы полностью обрабатывает 1 процесс.

vitalyas 25.02.2018 14:07

Демон на пхп, это бесконечный цикл. Процесс висит в озу и делает свои задачи и не грузит проц на 100%. Где глупость?

Белый шум 25.02.2018 14:34

Цитата:

Сообщение от vitalyas
В итоге получается, что обычный console.log(), при запросе двумя юзерами выполнится последовательно в одном процессе, сначала для первого, потом для второго, а не параллельно, как в двух одновременных процессах пхп?

Да

Цитата:

Сообщение от Nexus
Хотел сказать, что если процесс на 100% грузит CPU, то ничего удивительного в том, что другие пользователи в это время не могут получить ответ от машины нет.

В стандартном php получат, ибо разные процессы (или нити).

Цитата:

Сообщение от Nexus
Заставить машину ожидать какое-то время (видимо бесконечное) путем запуска бесконечного цикла - как минимум глупость, тем более в php.

Можно поставить sleep - результат будет тем же.

Цитата:

Сообщение от Nexus
Не знаком с nodejs и желания знакомиться нет, но я сильно сомневаюсь, что все запросы полностью обрабатывает 1 процесс.

Разумеется, можно запустить несколько процессов и балансировать нагрузку между ними тем же nginx. Но их все можно подвесить, если там есть такой код. В стандартном php есть лимиты, которые это разрулят, а в этих решениях таких защит не предусмотрено by design (если я правильно ошибаюсь).


Часовой пояс GMT +3, время: 13:12.