Javascript 带有SVG图标的Chrome扩展(Chrome.browserAction.setIcon)

Javascript 带有SVG图标的Chrome扩展(Chrome.browserAction.setIcon),javascript,google-chrome-extension,Javascript,Google Chrome Extension,我在我的Chrome扩展中使用可缩放的SVG图标 chrome.browserAction.setIcon({ tabId: tabId, path: '../icons/' + icon + '/scalable.svg' }); 我想根据一些参数切换图标,所以我有视觉反馈 我所意识到的是,当我快速切换图标时,Chrome会把事情弄得一团糟,我经常会看到错误的图标。我添加了console.log打印到代码中,以确保我正确地切换图标,并且我看到我的代码没有错误 看起来Chrome异步执

我在我的Chrome扩展中使用可缩放的SVG图标

chrome.browserAction.setIcon({
  tabId: tabId,
  path: '../icons/' + icon + '/scalable.svg'
});
我想根据一些参数切换图标,所以我有视觉反馈

我所意识到的是,当我快速切换图标时,Chrome会把事情弄得一团糟,我经常会看到错误的图标。我添加了
console.log
打印到代码中,以确保我正确地切换图标,并且我看到我的代码没有错误

看起来Chrome异步执行这种图标更改请求,而SVG到像素的转换有时需要比平常更长的时间。这会导致错误的执行顺序

例如,如果我将图标从A切换到B,然后切换到C;然后到D。。。最后我可能会看到C,尽管最后一次请求更改是将其切换到D

有没有办法解决这个恼人的问题

  • 使用
    Promise
  • 如果您经常调用
    setIcon
    ,请自己创建一个imageData缓存,并使用它而不是
    path
    ,因为API每次都会重新读取源图标并重新创建imageData
  • 以下是一个未经测试的通用示例:

    const queue={};
    常量缓存={};
    //自动清理队列,使其不会无限增长
    chrome.tabs.onRemoved.addListener(tabId=>delete queue[tabId]);
    异步函数setIcon(选项卡ID,图标){
    常量url='../icons/'+icon+'/scalable.svg';
    const imageData=wait(缓存[url]| |(缓存[url]=loadImageData(url));
    queue[tabId]=(queue[tabId]| Promise.resolve())。然后(()=>
    新承诺(解决=>
    chrome.browserAction.setIcon({tabId,imageData},resolve));
    }
    函数loadImageData(url){
    返回新承诺((解决、拒绝)=>{
    常量数据={};
    const img=新图像();
    img.src=url;
    img.onload=()=>{
    for(常量大小为[16,32]){
    const canvas=document.createElement('canvas');
    document.documentElement.appendChild(画布);
    canvas.width=canvas.height=size;
    const ctx=canvas.getContext('2d');
    ctx.drawImage(img,0,0);
    data[size]=ctx.getImageData(0,0,size,size);
    canvas.remove();
    }
    解析(数据);
    };
    img.onerror=拒绝;
    });
    }