1

一开始我认为问题在于chrome.runtime.sendMessage()我发送了两条消息。一个用于访问localstorage,另一个用于获取/读取文件数据,但在我将它们合并为一个后没有任何变化,sendMessage这意味着实际的问题是window.webkitRequestFileSystem()它返回的是前一个文件而不是当前文件。

有没有更好/更快的方式来存储客户端的东西?(我愿意尝试一切)?

清单.json

{
  "manifest_version": 2,

...
  "content_scripts": [
    {
      "matches": ["http://*/*", "https://*/*"],
      "js": ["content.js"],
      "run_at": "document_end"
    }
  ],
  "background": {
    "scripts": ["background.js"]
  },
  "permissions": [
    "unlimitedStorage"
  ]
}

背景.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);
    }

内容.js

chrome.runtime.sendMessage({method: "getTheme", url: location.href}, function(response) {
  console.log(response.data);
});
4

1 回答 1

5

由于您的问题不是SSCCE,因此很难对其进行测试,但我认为您的问题是对 JS 异步性质的理解。

那么您的代码将如何实际执行:

  1. 首先window.webkitRequestFileSystem(PERSISTENT, 0, successCallback, errorHandler);将被执行
  2. 然后sendResponse({data: theme});将使用存储在其中的任何内容发送响应theme
  3. 然后将根据文件请求成功调用任何successCallback一个。errorHandler如果successCallback将被调用,那么您的theme变量将填充您想要的值。但为时已晚,因为您已经发送了回复。

下次您传递消息时,您将收到以前的主题值(第 2 点),因为您的代码只有在您发送值之后才会找到新值。

一个解决方案可能是在找到所需的值后调用sendResponseinside successCallback(您必须sendResponse传入readFromFileStorage)。如果你这样做,那么你可以考虑添加sendResponseerrorHandler函数中,以确保你的代码总是能得到有效的响应。

如果您将移动sendResponse到回调中,那么您必须从addListener函数返回 true,否则addListener返回通道将被关闭并且不会发送响应。

于 2013-12-02T16:02:45.220 回答