节点JS + Express-异步请求

时间:2018-09-01 02:19:20

标签: node.js algorithm sorting express asynchronous

我正在尝试使用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;
}
}

这是我在其中创建名称空间的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 :(得分:1)

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

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

Node.js以单线程方式运行Javascript。因此,如果您要执行一些大的排序算法,那将使该单个线程无效直到完成。制作函数async完全对您没有帮助。所有要做的就是更改函数的返回值。它不会影响该函数中同步代码的运行方式。

如果您真的想在单个Javascript线程之外运行代码,则可以使用以下选项:

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

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

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

  

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

您不能在单个node.js进程中“在后台运行Javascript”。 node.js的体系结构无法正常工作。您的代码没有这样做。看来您误解了async函数的作用。

  

如果没有,我该怎么办?

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