GWo*_*ing 0 javascript sorting freeze
我的sort()函数存在瓶颈,例如:
list.sort(function (a,b) {return (a.value - b.value);});
Run Code Online (Sandbox Code Playgroud)
冻结浏览器几秒钟.
对于循环的相同情况,建议使用"超时"策略,例如此处描述的策略:
那么,问题是,这可以用排序方法实现吗?
*在评论讨论后编辑
// main_div is a div defined before
for (let i=0; i<list.length; i++) {
main_div.appendChild(document.getElementById(list[i].id));
}
Run Code Online (Sandbox Code Playgroud)
您可以使用本机sort方法执行排序,但是在单独的线程中,使用Web worker.Web工作人员将在完成其工作时通知.我已将其包装在ES6承诺中,因此您可以使用该then方法(请参阅下面的非承诺版本):
function asyncSort(data) {
// Return a promise
return new Promise(function (resolve) {
// function to be called by web worker:
function onmessage(e) {
e.data.sort();
postMessage(e.data);
}
// Create the worker, passing it the above code (as blob URL)
var worker = new Worker(URL.createObjectURL(
new Blob(['onmessage = ' + onmessage.toString()])));
// Capture the event when worker has finished
worker.onmessage = function (e) {
resolve(e.data); // resolve the promise
};
// Let worker execute the sort (async)
worker.postMessage(data);
});
}
// Sample call
asyncSort([2, 3, 1]).then(function (result) {
console.log(result); // [1, 2, 3]
});Run Code Online (Sandbox Code Playgroud)
非承诺版本如下所示:
function asyncSort(data, callback) {
function onmessage(e) {
e.data.sort();
postMessage(e.data);
}
var worker = new Worker(URL.createObjectURL(
new Blob(['onmessage = ' + onmessage.toString()])));
worker.onmessage = function (e) {
callback(e.data);
};
worker.postMessage(data);
}
asyncSort([2, 3, 1], function (result) {
console.log(result);
});Run Code Online (Sandbox Code Playgroud)
请注意,IE(至少版本11)会在Blob URL上引发安全性错误.作为解决方法,您必须使用以下内容创建单独的JS脚本文件:
onmessage = function (e) {
e.data.sort();
postMessage(e.data);
}
Run Code Online (Sandbox Code Playgroud)
...然后将该脚本作为Worker原始脚本中的URL引用:
new Worker('script.js')
Run Code Online (Sandbox Code Playgroud)