首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >基于javascript的抢占式后台工作调度的通用解决方案

基于javascript的抢占式后台工作调度的通用解决方案
EN

Stack Overflow用户
提问于 2018-02-15 03:04:58
回答 1查看 40关注 0票数 0

这是一个场景:当我的web应用程序启动时,我希望从本地存储中的多个表中加载数据(使用indexedDB)。我将这项工作委托给一位web工作者。它将依次加载每个表,并在加载每个表时使用数据触发一条消息。在主线程上,侦听器将接收消息并将数据存储在缓存中。

但是假设用户按下一个按钮来查看特定表的数据。应用程序调用一个检查缓存的函数,发现该表的数据尚未加载。

该函数如何等待该表的数据被缓存,以便它可以返回数据?更重要的是,如果表被安排在最后装入,该怎么办?此函数如何向web worker发送一条消息,以确定加载特定表的优先顺序,以便其数据尽快可用?

这个抢占式调度问题的干净解决方案的一般模式是什么?如果可能的话,我想避免轮询。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-02-15 03:54:54

Worker可以使用一个异步队列,该队列包含所有要加载的表,并在某个优先级之后进行排序,因此您可以对某些表进行优先级排序,并将它们排序到表的前面。因为你还没有展示一个真正的实现,所以这里是一个更通用的版本:

代码语言:javascript
复制
 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)这样的东西来允许进程消息传递中断它……

一个示例实现可以是一个图像加载器:

代码语言:javascript
复制
 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");
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/48794471

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档