我知道这是一个相当古老的问题,但我遇到了类似的情况,仍然没有找到简单的解决方案。
我修改了一个现有的快速排序并发布了一个包,它定期在此处放弃对事件循环的执行:
https ://www.npmjs.com/package/qsort-async
如果您熟悉传统的快速排序,我唯一的修改是对执行分区的初始函数。基本上,该函数仍然在原地修改数组,但现在返回一个承诺。如果它试图在一次迭代中处理太多元素,它会停止执行 eventloop 中的其他事情。(我相信我指定的默认大小是 10000)。
注意:在这里使用 setImmedate 而不是 process.nextTick 或 setTimeout 很重要。nextTick 实际上会将您的执行放在进程 IO 之前,并且您在响应与 IO 相关的其他请求时仍然会遇到问题。setTimeout 太慢了(我相信其他答案之一链接了一个演示)。
注意 2:如果像合并排序这样的东西更符合您的风格,您可以在排序的“合并”功能中执行相同的逻辑。
const immediate = require('util').promisify(setImmediate);
async function quickSort(items, compare, left, right, size) {
let index;
if (items.length > 1) {
index = partition(items, compare, left, right);
if (Math.abs(left - right) > size) {
await immediate();
}
if (left < index - 1) {
await quickSort(items, compare, left, index - 1, size);
}
if (index < right) {
await quickSort(items, compare, index, right, size);
}
}
return items;
}
完整代码在这里:https ://github.com/Mudrekh/qsort-async/blob/master/lib/quicksort.js