Узел JS + Express - Асинхронный запрос - PullRequest
0 голосов
/ 01 сентября 2018

Я пытаюсь узнать кое-что с Node.js + Express в качестве веб-сервера, пытаясь сделать его асинхронным. Я создал приложение для проверки временной сложности алгоритмов сортировки (вдохновение для домашней работы колледжа), но оно не работает асинхронно, как я планировал. Любой другой вызов REST на сервер Express блокируется до тех пор, пока не завершится выполнение предыдущего кода сортировки. Я также использую 'express-namespace-routs', чтобы иметь некоторые пространства имен, чтобы это выглядело как вызов API.

Это мой класс Сортировка:

class Sort {
   static async binarySearch(array, inf, sup, key) {
    let half = inf + Math.floor((sup - inf) / 2);

    if (inf == sup) return inf;
    else if (key > array[half]) return this.binarySearch(array, half + 1, sup, key);
    else if (key < array[half]) return this.binarySearch(array, inf, half, key);
    else return half;
}

static async binaryInsertionSort(array) {
    let changes = 0;
    const time = process.hrtime();
    for (let j = 1; j < array.length; j++) {
        let key = array[j];
        let i = j - 1;
        let posicao = await this.binarySearch(array, 0, j, key);
        while (i >= posicao) {
            array[i + 1] = array[i];
            i--;
            changes++
        }
        array[posicao] = key;
    }
}

static async createRandomArray(size) {
    let array = await this.createSortedArray(size);
    for (let s = size; s > 0; s--) {
        let index = Math.floor(Math.random() * s);

        let temp = array[s - 1];
        array[s - 1] = array[index];
        array[index] = temp;
    }
    return array;
}
}

Это часть моего файла index.js, где я создаю пространство имен:

routes.prefix('/sorted', sorted => {
    sorted.get('/binaryInsertion/:size', async (req, res) => {
    Sort.createRandomArray(req.params.size)
      .then(array => Sort.binaryInsertionSort(array))
      .then(data => res.json(data))
      .catch(err => res.send(err));
  });
});

А это я звоню на сервер:

$.ajax(`${arrayType}/${sortingAlgorithm}/${arraySize}`).then(console.log);

Есть идеи? Что я мог делать не так? Все выглядит асинхронным для меня. Проблема не только в binaryInsertionSort, поэтому я думаю, что проблема не в коде алгоритма, так как он блокирует запросы для всех моих уже реализованных алгоритмов

1 Ответ

0 голосов
/ 01 сентября 2018

Во-первых, весь ваш код синхронен и блокируется. Это все местный Javascript. Вы не вызываете никаких встроенных асинхронных операций.

Нельзя заставить нормальный Javascript в node.js работать асинхронно. Единственными вещами, которые работают асинхронно, являются вещи, которые имеют некоторую асинхронную реализацию собственного кода, такую ​​как файловый ввод / вывод или работа в сети. И затем код, который использует обратные вызовы или обещания для этих изначально асинхронных операций, вернет управление обратно в цикл обработки событий (что позволяет другим вещам выполняться) и затем возобновится, когда будет вызван их обратный вызов. Но ничто из этого не позволяет вашему собственному Javascript «запускаться в фоновом режиме» или «запускаться без блокировки и использования одного потока Javascript» в файле node.js.

Node.js запускает ваш Javascript как однопоточный. Итак, если вы выполняете какой-то большой алгоритм сортировки, то этот поток будет работать только до тех пор, пока он не будет завершен. Вам вообще не поможет сделать функцию async. ВСЕ, что делает, это изменяет возвращаемое значение функции. Это не влияет на работу синхронного кода в этой функции.

Если вы действительно хотите запустить свой код вне одного потока Javascript, тогда у вас есть следующие опции:

  1. Используйте модуль child_process, чтобы создать второй процесс node.js для запуска кода сортировки.
  2. Используйте модуль кластера для кластеризации приложения, чтобы у вас было несколько идентичных процессов, обслуживающих запросы, и пока один из них выполняет алгоритм сортировки, другой может обрабатывать другие запросы.
  3. Напишите собственный код, который запускает вашу сортировку в другом потоке и передает результат асинхронно (вероятно, через событие обратного вызова в очереди событий).
  4. Создайте набор рабочих процессов node.js, с которыми вы общаетесь, используя свою любимую форму межпроцессного взаимодействия, а затем вы можете создать рабочую очередь, в которой вы передаете элементы своим рабочим процессам и обрабатывает задачи, потребляющие ресурсы ЦП, за пределами основного узла. Приложение JS.

С чего бы это блокировать? Я называю это асинхронно.

Вы не вызываете это асинхронно. Функция async не делает ничего асинхронным. Все, что он делает, это позволяет await внутри и заставляет возвращаемое значение функции быть обещанием. Любой Javascript внутри этой функции по-прежнему работает с одним потоком node.js и блокируется во время его работы. Если вы выполните await для функции, которая возвращает обещание, которое приостановит выполнение функции до тех пор, пока обещание не разрешится и не разрешит выполнение других вещей, но если все, что у вас есть в любой из ваших функций, - это синхронный код, то все будет просто собирается работать синхронно (есть одно крошечное исключение для обработчиков .then(), которое просто заставляет их ждать следующего цикла цикла событий), но все равно не позволяет синхронному коду запускаться «в фоновом режиме» или что-то в этом роде .

Я просто хочу, чтобы эта функция работала в "фоновом режиме", не будет ли мой код делать это?

Вы не можете "запускать Javascript в фоновом режиме" в одном процессе node.js. Архитектура node.js не работает таким образом. Ваш код этого не делает. Похоже, вы неправильно поняли, что делает функция async.

Если нет, что я мог сделать?

См. Четыре пронумерованных варианта выше.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...