一开始我认为问题出在chrome.runtime.sendMessage()
我发送了两条消息。一个用于访问localstorage
,另一个用于获取/读取文件数据,但在我将它们合并到一个sendMessage
后没有任何更改,这意味着实际问题是window.webkitRequestFileSystem()
它返回了以前的文件而不是现在的那个。
是否有更好/更快的方式存储客户端? (我愿意尝试一切)?
的manifest.json
{
"manifest_version": 2,
...
"content_scripts": [
{
"matches": ["http://*/*", "https://*/*"],
"js": ["content.js"],
"run_at": "document_end"
}
],
"background": {
"scripts": ["background.js"]
},
"permissions": [
"unlimitedStorage"
]
}
background.js
var theme = '';
chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) {
if(request.method == "getTheme") {
themes = JSON.parse(localStorage["themes"]);
themeName = "";
for (var i = themes.length - 1; i >= 0; i--) {
if(request.url.indexOf(themes[i]) !== -1) {
themeName = themes[i];
}
};
window.webkitRequestFileSystem(window.PERSISTENT, 0, readFromFileStorage.bind(window, themeName), errorHandler);
sendResponse({data: theme});
}
});
function readFromFileStorage(filename, fs) {
fs.root.getFile(filename, {}, function(fileEntry) {
fileEntry.file(function(file) {
var reader = new FileReader();
reader.onloadend = function(e) {
theme = this.result;
};
reader.readAsText(file);
}, errorHandler);
}, errorHandler);
}
function errorHandler(e) {
console.log('Error: ' + e.message);
}
content.js
chrome.runtime.sendMessage({method: "getTheme", url: location.href}, function(response) {
console.log(response.data);
});
答案 0 :(得分:5)
由于您的问题不是SSCCE,因此很难对其进行测试,但我认为您的问题是了解JS异步性质。
那么你的代码将如何实际执行:
window.webkitRequestFileSystem(PERSISTENT, 0, successCallback, errorHandler);
sendResponse({data: theme});
将使用theme
successCallback
errorHandler
或successCallback
。如果将调用theme
,那么您的sendResponse
变量将填充您想要的值。但是,由于你已经发送了回复,这将会很晚。下次传递消息时,您将收到上一个主题值(第2点),因为您的代码只有在您发送值后才会找到新值。
解决方案可能是在您找到所需的值后调用successCallback
内的sendResponse
(您必须将readFromFileStorage
传递到sendResponse
)。如果您这样做,那么您可以考虑将errorHandler
添加到sendResponse
函数中,以确保您的代码始终获得有效的响应。
如果您将addListener
移动到回调中,则必须从addListener
函数返回true,否则在{{1}}返回通道将被关闭且响应将不会发送。