这是一个场景:当我的web应用程序启动时,我希望从本地存储中的多个表中加载数据(使用indexedDB)。我将这项工作委托给一位web工作者。它将依次加载每个表,并在加载每个表时使用数据触发一条消息。在主线程上,侦听器将接收消息并将数据存储在缓存中。
但是假设用户按下一个按钮来查看特定表的数据。应用程序调用一个检查缓存的函数,发现该表的数据尚未加载。
该函数如何等待该表的数据被缓存,以便它可以返回数据?更重要的是,如果表被安排在最后装入,该怎么办?此函数如何向web worker发送一条消息,以确定加载特定表的优先顺序,以便其数据尽快可用?
这个抢占式调度问题的干净解决方案的一般模式是什么?如果可能的话,我想避免轮询。
发布于 2018-02-15 03:54:54
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");
https://stackoverflow.com/questions/48794471
复制相似问题