从回调调用的addListener的sendResponse返回上一条消息

waa*_*dim 1 webkit google-chrome google-chrome-extension

一开始我认为问题在于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"
  ]
}
Run Code Online (Sandbox Code Playgroud)

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);
    }
Run Code Online (Sandbox Code Playgroud)

content.js

chrome.runtime.sendMessage({method: "getTheme", url: location.href}, function(response) {
  console.log(response.data);
});
Run Code Online (Sandbox Code Playgroud)

bum*_*mbu 5

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

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

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

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

一个解决办法可能是调用sendResponse里面successCallback你发现你的所需值后(你必须通过sendResponse进入readFromFileStorage).如果您这样做,那么您可以考虑添加sendResponseerrorHandler函数中以确保您的代码始终获得有效的响应.

如果您将sendResponse进入回调,则必须从addListener函数返回true ,否则addListener将关闭返回通道并且不会发送响应.