This is a mobile optimized page that loads fast, if you want to load the real page, click this text.

Вопрос async, событийный цикл

Wa3Rix

Активный участник
Автор темы
high coder
19 Ноя 2020
32
4
30
Не могу разобраться с принципом работы на практике. В теории все вроде бы понял, с начало выполняется синхронный код, а остальное уходит в стек задач или микро.
Потом по ходу дела, само тело промиса синхронно, так, да? А код в then() асинхронен, но в чем профит от того что код асинхронен, если выполнение идет в 1-м потоке?

Я так понимаю если выполнять синхронно ресурсоемкие задачи, то на время выполнения сервер стопится игрокам перестает отправляться синхра?

У меня к примеру есть функция которая при выбрасывании вещи из инвентаря перебирает все обьекты (маппинг) на сервере и если игрок ближе 5 метров к обьекту добавляет к нему инфу о выкинутой вещи, а если рядом нету обьектов создает новый. Логично что выкинуть игроки много могут чего и перебор будет трудоемким, но как это будет выполнятся?


JavaScript:
let start_time = {};
function startTimer(name)
{
    let curr_date = new Date();
    start_time[name] = curr_date.getTime();
}

function stopTimer(name)
{
    let curr_date = new Date();
    return (curr_date.getTime() - start_time[name]);
}

function delay() {
    return new Promise(resolve => setTimeout(resolve, 500));
}

async function Tasty()
{
    Some.droped.forEach(async (value) =>
    {
        await delay();
        console.log(value);
    });


    console.log("Tasty worked");
}

function main()
{
    startTimer("startTimer");
    console.log("startTimer " + stopTimer("startTimer") + " ms.");

    startTimer("Tasty();");
    Tasty();
    console.log("Tasty() " + stopTimer("Tasty();") + " ms.");
    const Test2 = async () =>
    {
        startTimer("Test2")
        startTimer("then()")
        let arr = [];
        for(let i=0; i<1000000; i++)
        {
            if(i % 2 == 0 && typeof(i) == "number")
                arr.push(`U wasted time ${i} times...`);
        }

        return "Test2 is end " + stopTimer("Test2");
    }

    const TestThen = async () =>
    {
        // nothing
        return true;
    }

    startTimer("TestThen()");
    TestThen().then(() =>
    {
        let arr = [];
        for(let i=0; i<1000000; i++)
        {
            if(i % 2 == 0 && typeof(i) == "number")
                arr.push(`U wasted time ${i} more times...`);
        }
    });
    console.log("TestThen() " +stopTimer("TestThen()") +" ms.");

    startTimer("Test2()");
    Test2().then((text) => {console.log(text); console.log("then() " +stopTimer("then()") +" ms."); });
    console.log("Test2() " + stopTimer("Test2()") + " ms.");
    console.log("Main end");

}main();

Результат выполнения:
Код:
startTimer 0 ms.
Tasty worked
Tasty() 18 ms.
TestThen() 1 ms.
Test2() 442 ms.
Main end
Test2 is end 441
then() 978 ms.

Как видно по таймеру самое длительное выполнение у "Test2()", "Test2" и "then()".
Таймер "Test2" считает синхронную операцию, "then" тоже, но сами они находятся в асинхронной функции, по этому закончили работу после "Main end" (тут всё норм). Но "Test2()" почему столько времени потребовал?
Еще 1 момент "then" выполнялся 978 м.с., но без "TestThen()", он занимает ~400 m.s. Что указывает на то что даже при вызове асинхронной функции, другие вынуждены ждать.
Код:
startTimer 1 ms.
Tasty worked
Tasty() 4 ms.
Test2() 384 ms.
Main end
Test2 is end 384
then() 401 ms.
Получается что при любой конструкции код будет стопится? Или можно как-то параллельно выполнить код?
 
Последнее редактирование:

X-Clusiv

Модератор
Команда форума
high coder
4 Окт 2020
583
276
161
29
так проверяй на клиенте, а не на сервере, а на сервере уже делай проверку действительно ли он так близок к этому объекту.
 

Wa3Rix

Активный участник
Автор темы
high coder
19 Ноя 2020
32
4
30
Изначально планировал сделать только перебор при поднятии на клиенте. Но если подумать, то во-первых придется отправлять клиенту все обьекты сервера что бы он потом мог проверять, на первых порах обьектов будет не много, но спустя время может такое количество накопится что данные в чистом виде (байты) будут весить десятки МБ, а передаются они вроде как только JSON строкой. Это тоже можно считать большой нагрузкой. И еще момент, когда напишут софт под рейдж или он уже даже есть. То можно будет сделать волхак который будет подсвечивать самые ценные тайники игроков по всей карте.

Возможно я сделаю стример который накладывает сетку на карту и при входе в квадрат что бы клиент запрашивал обьекты в этой зоне, это решит обе проблемы. Но всё же интересует что с сервером происходит во время выполнения таких задач и есть ли какая-то возможность параллельного выполнения?
 
Последнее редактирование:

X-Clusiv

Модератор
Команда форума
high coder
4 Окт 2020
583
276
161
29
А зачем отправлять объекты клиенту? Все что создается на сервере, синхронизируется между игроками автоматически. Для перебора по радиусу есть https://wiki.rage.mp/index.php?title=Pool::forEachInStreamRange
 

Wa3Rix

Активный участник
Автор темы
high coder
19 Ноя 2020
32
4
30
Так это заскриптованые обьекты будут, что бы отделить их от обычных. Обьект создается только для визуализации, а что добавится в инвентарь если взять, хранится в отдельном массиве.
 

Cook old

Активный участник
8 Ноя 2020
6
4
40
Реакции: Евгений Бусько