以下是该方案: 当我的Web应用程序启动时,我想从本地存储中的几个表加载数据(使用indexedDB)。我将这项工作委托给网络工作者。它将依次加载每个表,并在加载每个表时触发包含数据的消息。在主线程上,侦听器将接收消息并将数据存储在缓存中。
但是,让我们说用户按下按钮来查看特定表格的数据。该应用程序调用一个检查缓存的函数,并发现该表的数据尚未加载。
此函数如何等待该表的数据被缓存,以便它可以返回数据?更重要的是,如果计划最后加载表怎么办?该函数如何向Web工作者发送消息以确定加载该特定表的优先级,以便尽快获得其数据?
这种先发制人的调度问题的清洁解决方案的一般模式是什么?我想尽可能避免民意调查。
答案 0 :(得分:1)
Worker可以使用包含要加载的所有表的异步队列,并在特定优先级之后进行排序,因此您可以优先处理某些表,并将它们排序到表的前面。你没有展示出真正的实现,这是一个更通用的版本:
class AsyncPriorityQueue {
constructor(task){
this.task = task;
this.queue = [];
}
push(element, priority = 0){
const pos = this.queue.findIndex(el => el.priority < priority) + 1;
this.queue.splice(pos, 0, {element, priority});
if(this.running) return;
this.running = true;
this._run();
}
prioritize(element, priority = 10){
const pos = this.queue.findIndex(el => el.element === element);
if(pos != -1) this.queue.splice(pos, 1);
this.push(element, priority);
}
async _run(){
while(this.queue.length)
await this.task(this.queue.shift().element);
}
}
注意:如果任务不是异步的,你应该使用像setTimeout(next, 0)
这样的过程消息来中断它......
示例实现可以是图像加载器:
class ImageLoader extends AsyncPriorityQueue {
constructor(){
super(function task(url){
const img = new Image();
img.src = url;
return new Promise(res => img.onload = res);
});
}
}
const loader = new ImageLoader;
loader.push("a.jpg");
loader.push("b.jpg", 1); // a bit more important
// Oh, wait:
loader.prioritize("a.jpg");