2015-11-12 210 views
0

我正在做一个chrome扩展,通过弹出窗口阻止添加到本地存储的特定站点。我认为这个代码中的问题是,它在chrome.storage.local.get的回调完成之前返回。如何在返回之前等待一段时间?同步执行异步功能

chrome.webRequest.onBeforeRequest.addListener(
function(details) { 

var matched = false; 

chrome.storage.local.get ('blocked_sites', function (sites) { 
    var bsites = sites.blocked_sites; 
    for (i = 0, size = bsites.length; i < size; i++) { 
    if (details.url.indexOf("://" + bsites[i] + "/") != -1) { 
     matched = true; 
    } // end if 
    } // end for 

}); 
// WAIT HERE FOR VALUE OF MATCHED TO BE SET BY CALLBACK 
return { cancel: matched }; 
}, 
{ urls: ["<all_urls>"] }, 
["blocking"]); 

chrome.storage.local.set({'blocked_sites': [ 'www.topnotchdev.com'] }, null); 
+3

你不能让它等待。您只能将代码重写为异步。 – Bergi

+0

是的,我试图让它通过使用循环等待,并阻止线程。告诉我如何重写它? – mallaudin

回答

2

不能调用任何异步函数在webRequest阻止听众。这是没有办法的,哈克或其他。由于JavaScript是单线程的,因此基本上是不可能的;在当前函数完成执行之前,异步操作甚至不会启动。

这意味着你不能依赖异步存储;您必须拥有本地同步缓存。

blocked_sites保存为变量,并在chrome.storage.onChanged事件中更新它。这样,您将拥有设置的同步缓存。

+0

感谢您的快速回复@Xan。但局部变量会在脚本执行后破坏,我将如何在下一次执行脚本时填充它? – mallaudin

+1

从'chrome.storage'。不要在'webRequest'监听器中调用'chrome.storage'。 – Xan

+0

在代码中发表评论也不起作用。提出一个新问题(因为这个问题已经收到了一些答案)。在你做之前,试着自己想一些。 – Xan

0

随着您的代码结构化,您将无法在回调后执行return { cancel: matched };。原因是因为return { cancel: matched };运行在一个执行框架(与调用chrome.storage.local.get相同)并且回调在未来的某个执行框架中运行。当你调用异步方法时,只有在回调执行的时候return { cancel: matched };已经执行,它才能将回调插入到事件循环中。