我正在尝试使用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中,所以我认为问题不在算法代码中,因为它阻止了我已经实施的所有算法的请求
答案 0 :(得分:1)
首先,您的所有代码都是同步且阻塞的。全部都是本地Javascript。 您不会调用任何内置的异步操作。
您不能使node.js中的普通Javascript异步运行。唯一异步运行的是具有某种本机代码实现(例如文件I / O或网络)异步的事物。并且,对那些本机异步操作使用回调或promise的代码将把控制权返回到事件循环(允许其他事情运行),然后在调用其回调时恢复执行。但是,这些都不允许您自己的Javascript在node.js中“在后台运行”或“在不阻止和使用单个Javascript线程的情况下运行”。
Node.js以单线程方式运行Javascript。因此,如果您要执行一些大的排序算法,那将使该单个线程无效直到完成。制作函数async
完全对您没有帮助。所有要做的就是更改函数的返回值。它不会影响该函数中同步代码的运行方式。
如果您真的想在单个Javascript线程之外运行代码,则可以使用以下选项:
为什么会阻止?我正在异步调用它。
您不是异步调用它。 async
函数不会使任何东西异步。它所做的只是允许await
内在,并强制函数的返回值是一个承诺。该函数内的任何Javascript仍将使用单个node.js线程运行,并且在运行时仍会阻塞。如果对返回诺言的函数执行await
,这将暂停函数的执行,直到诺言得到解决并允许其他事情运行,但是如果所有函数中只有同步代码,则一切都将同步运行(.then()
处理程序有一个微小的例外,它使它们等到事件循环的下一个周期),但是仍然不允许同步代码“在后台”运行或类似的东西。
我只希望该函数在“后台”运行,我的代码不会这样做吗?
您不能在单个node.js进程中“在后台运行Javascript”。 node.js的体系结构无法正常工作。您的代码没有这样做。看来您误解了async
函数的作用。
如果没有,我该怎么办?
请参见上面的四个编号选项。