Node JS + Express - 异步请求

Raf*_*ert 1 sorting algorithm asynchronous node.js express

我正在尝试使用 Node.js + Express 作为 Web 服务器来学习一些东西,试图使其异步。我创建了一个应用程序来测试排序算法的时间复杂度(大学作业的灵感),但它并没有按照我的预期异步工作。对 Express 服务器的任何其他 REST 调用都会被阻止,直到前一个排序代码完成运行。我还使用“express-namespace-routes”来拥有一些命名空间,因此它看起来像一个 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;
}
}
Run Code Online (Sandbox Code Playgroud)

这是我的 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));
  });
});
Run Code Online (Sandbox Code Playgroud)

这是我给服务器打电话:

$.ajax(`${arrayType}/${sortingAlgorithm}/${arraySize}`).then(console.log);
Run Code Online (Sandbox Code Playgroud)

任何想法?我可能做错了什么?对我来说一切看起来都是异步的。问题不仅出在binaryInsertionSort中,所以我认为问题不在算法代码中,因为它阻止了对我所有已经实现的算法的请求

jfr*_*d00 5

首先,所有代码都是同步和阻塞的。这都是本地 Javascript。您不调用任何内置异步操作。

你不能让node.js 中的普通Javascript 异步运行。唯一异步运行的事物是具有某种异步本机代码实现的事物,例如文件 I/O 或网络。然后,使用回调或承诺执行那些本机异步操作的代码会将控制权返回到事件循环(允许其他操作运行),然后在调用回调时恢复。但是,这些都不允许您自己的 Javascript 在 Node.js 中“在后台运行”或“无阻塞运行并使用单个 Javascript 线程”。

Node.js 以单线程方式运行 Javascript。因此,如果您正在执行一些大型排序算法,那么这将限制单个线程直到完成。它根本不能帮助你实现这个功能async。所做的只是更改函数的返回值。它不会影响该函数中同步代码的运行方式。

如果您确实想在单个 Javascript 线程之外运行代码,那么您有以下选择:

  1. 使用 child_process 模块创建第二个 node.js 进程来运行排序代码。
  2. 使用 cluster 模块对您的应用程序进行集群,以便您拥有多个相同的进程来处理请求,并且当一个进程运行排序算法时,另一个进程可以处理其他请求。
  3. 编写本机代码,在另一个线程中运行排序并异步传回结果(可能通过事件队列中的回调事件)。
  4. 创建一组使用您最喜欢的进程间通信形式进行通信的 Node.js 工作进程,然后您可以创建工作队列,将项目传递给工作进程,并处理主 Node.js 应用程序之外的 CPU 消耗任务。

为什么会阻塞?我正在异步调用它。

您没有异步调用它。函数async不会使任何事情异步。它所做的只是允许await内部并强制函数的返回值成为一个承诺。该函数内的任何 Javascript 仍然使用单个 node.js 线程运行,并且在运行时仍然阻塞。如果你对一个await返回 Promise 的函数执行 an 操作,这将暂停该函数的执行,直到 Promise 解析并允许其他东西运行,但是如果你的任何函数中只有同步代码,那么一切都会同步运行(处理程序有一个微小的异常.then(),这只会让它们等到事件循环的下一个周期),但它仍然不允许同步代码“在后台”运行或类似的东西。

我只是希望该函数在“后台”运行,我的代码不会这样做吗?

您无法在单个 Node.js 进程中“在后台运行 Javascript”。Node.js 的架构并不是这样工作的。你的代码没有这样做。看来您误解了函数的作用async

如果没有,我能做什么?

请参阅上面的四个编号选项。