草庐IT

javascript - Chrome扩展: wait for storage.同步获取远程数据

coder 2025-03-08 原文

我有一个扩展程序可以读取带有时间戳的消息提要并提醒用户注意它们。

我跟踪自用户打开消息以来的最高时间戳,低于该时间戳的任何内容均被“已读”。它运作良好,但当用户安装了多个 Chrome 时,问题就来了:他看到的是他已经在另一台机器上阅读过的项目。

输入 chrome.storage.sync API .我可以设置最高时间戳以在实例之间同步,但这会给我带来竞争条件。

如果我在浏览器启动或从 sleep 中唤醒后立即使用 chrome.storage.sync.get,它将获取陈旧的本地数据并且不会等待同步发生 - 经测试真的。因此,用户仍然会收到警报,即使在警报被清除之前的一小段时间内也是如此 - 这令人困惑。

我可以检测扩展启动,我可以(某种程度上)检测从 sleep 中唤醒。甚至可能是线下/线上事件。 但是接下来我该怎么做才能让 Chrome 有机会同步数据?一个天真的解决方案是这样的:

var syncSleepTimeout = null;

function getUpAndRunning(){
  clearTimeout(syncSleepTimeout);
  syncSleepTimeout = null;
  doActualWork();
}

// Called upon wakeup/start/online event
function justWokeUp(){
  // Give sync a chance to happen
  syncSleepTimeout = setTimeout(getUpAndRunning, 3000);
}

chrome.storage.onChanged.addListener(function(changes, area){
  if(area === "sync" && syncSleepTimeout) getUpAndRunning();
});

据我所知,chrome.storage.sync 不提供任何状态信息或事件,甚至不提供用户是否实际启用了云同步。我提交了几个 feature requests为此,但它们完全被忽略了

  1. 是否有更优雅的解决方案?
  2. 什么是检测唤醒/获取在线事件的可靠解决方案?

最佳答案

这里是存储 API 的作者。我显然没有足够的声誉来回复评论线程。无论如何,同步做它的事情和网络状态/事件肯定不会紧密耦合。即使计算机处于离线状态,同步也会“完成”,但如果计算机在线,则同步可能不会立即“完成”。

像 chrome.storage.onStabilized 这样的事件,在某种形式下,是一个中等频率的请求。但是,除了 Storage API 之外还有一些复杂性。声称已加载同步作为推断计算机之间的障碍的某种方式将是一个误导性的 API。同步服务器不一定以这种方式连接。

例如即使用户已经在计算机 A 上阅读了某些内容,您更新了存储,用户打开了计算机 B,同步表明它已加载......这并不一定保证计算机 A 的更改已完全提交并推送给客户端。

因此,我们通常建议容忍这种不确定性。就像您所做的那样,在积极推断系统状态之前给予一点宽容。也许确实使用 navigator.onLine 作为粗略指标。

关于javascript - Chrome扩展: wait for storage.同步获取远程数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24013718/

有关javascript - Chrome扩展: wait for storage.同步获取远程数据的更多相关文章

  1. ruby - 解析 RDFa、微数据等的最佳方式是什么,使用统一的模式/词汇(例如 schema.org)存储和显示信息 - 2

    我主要使用Ruby来执行此操作,但到目前为止我的攻击计划如下:使用gemsrdf、rdf-rdfa和rdf-microdata或mida来解析给定任何URI的数据。我认为最好映射到像schema.org这样的统一模式,例如使用这个yaml文件,它试图描述数据词汇表和opengraph到schema.org之间的转换:#SchemaXtoschema.orgconversion#data-vocabularyDV:name:namestreet-address:streetAddressregion:addressRegionlocality:addressLocalityphoto:i

  2. ruby - 使用 C 扩展开发 ruby​​gem 时,如何使用 Rspec 在本地进行测试? - 2

    我正在编写一个包含C扩展的gem。通常当我写一个gem时,我会遵循TDD的过程,我会写一个失败的规范,然后处理代码直到它通过,等等......在“ext/mygem/mygem.c”中我的C扩展和在gemspec的“扩展”中配置的有效extconf.rb,如何运行我的规范并仍然加载我的C扩展?当我更改C代码时,我需要采取哪些步骤来重新编译代码?这可能是个愚蠢的问题,但是从我的gem的开发源代码树中输入“bundleinstall”不会构建任何native扩展。当我手动运行rubyext/mygem/extconf.rb时,我确实得到了一个Makefile(在整个项目的根目录中),然后当

  3. ruby - 简单获取法拉第超时 - 2

    有没有办法在这个简单的get方法中添加超时选项?我正在使用法拉第3.3。Faraday.get(url)四处寻找,我只能先发起连接后应用超时选项,然后应用超时选项。或者有什么简单的方法?这就是我现在正在做的:conn=Faraday.newresponse=conn.getdo|req|req.urlurlreq.options.timeout=2#2secondsend 最佳答案 试试这个:conn=Faraday.newdo|conn|conn.options.timeout=20endresponse=conn.get(url

  4. ruby - Ruby 有 `Pair` 数据类型吗? - 2

    有时我需要处理键/值数据。我不喜欢使用数组,因为它们在大小上没有限制(很容易不小心添加超过2个项目,而且您最终需要稍后验证大小)。此外,0和1的索引变成了魔数(MagicNumber),并且在传达含义方面做得很差(“当我说0时,我的意思是head...”)。散列也不合适,因为可能会不小心添加额外的条目。我写了下面的类来解决这个问题:classPairattr_accessor:head,:taildefinitialize(h,t)@head,@tail=h,tendend它工作得很好并且解决了问题,但我很想知道:Ruby标准库是否已经带有这样一个类? 最佳

  5. ruby - 从 Ruby 中的主机名获取 IP 地址 - 2

    我有一个存储主机名的Ruby数组server_names。如果我打印出来,它看起来像这样:["hostname.abc.com","hostname2.abc.com","hostname3.abc.com"]相当标准。我想要做的是获取这些服务器的IP(可能将它们存储在另一个变量中)。看起来IPSocket类可以做到这一点,但我不确定如何使用IPSocket类遍历它。如果它只是尝试像这样打印出IP:server_names.eachdo|name|IPSocket::getaddress(name)pnameend它提示我没有提供服务器名称。这是语法问题还是我没有正确使用类?输出:ge

  6. ruby - 获取模块中定义的所有常量的值 - 2

    我想获取模块中定义的所有常量的值:moduleLettersA='apple'.freezeB='boy'.freezeendconstants给了我常量的名字:Letters.constants(false)#=>[:A,:B]如何获取它们的值的数组,即["apple","boy"]? 最佳答案 为了做到这一点,请使用mapLetters.constants(false).map&Letters.method(:const_get)这将返回["a","b"]第二种方式:Letters.constants(false).map{|c

  7. ruby-on-rails - 获取 inf-ruby 以使用 ruby​​ 版本管理器 (rvm) - 2

    我安装了ruby​​版本管理器,并将RVM安装的ruby​​实现设置为默认值,这样'哪个ruby'显示'~/.rvm/ruby-1.8.6-p383/bin/ruby'但是当我在emacs中打开inf-ruby缓冲区时,它使用安装在/usr/bin中的ruby​​。有没有办法让emacs像shell一样尊重ruby​​的路径?谢谢! 最佳答案 我创建了一个emacs扩展来将rvm集成到emacs中。如果您有兴趣,可以在这里获取:http://github.com/senny/rvm.el

  8. Ruby 从大范围中获取第 n 个项目 - 2

    假设我有这个范围:("aaaaa".."zzzzz")如何在不事先/每次生成整个项目的情况下从范围中获取第N个项目? 最佳答案 一种快速简便的方法:("aaaaa".."zzzzz").first(42).last#==>"aaabp"如果出于某种原因你不得不一遍又一遍地这样做,或者如果你需要避免为前N个元素构建中间数组,你可以这样写:moduleEnumerabledefskip(n)returnto_enum:skip,nunlessblock_given?each_with_indexdo|item,index|yieldit

  9. ruby - Net::HTTP 获取源代码和状态 - 2

    我目前正在使用以下方法获取页面的源代码:Net::HTTP.get(URI.parse(page.url))我还想获取HTTP状态,而无需发出第二个请求。有没有办法用另一种方法做到这一点?我一直在查看文档,但似乎找不到我要找的东西。 最佳答案 在我看来,除非您需要一些真正的低级访问或控制,否则最好使用Ruby的内置Open::URI模块:require'open-uri'io=open('http://www.example.org/')#=>#body=io.read[0,50]#=>"["200","OK"]io.base_ur

  10. c - mkmf 在编译 C 扩展时忽略子文件夹中的文件 - 2

    我想这样组织C源代码:+/||___+ext||||___+native_extension||||___+lib||||||___(Sourcefilesarekeptinhere-maycontainsub-folders)||||___native_extension.c||___native_extension.h||___extconf.rb||___+lib||||___(Rubysourcecode)||___Rakefile我无法使此设置与mkmf一起正常工作。native_extension/lib中的文件(包含在native_extension.c中)将被完全忽略。

随机推荐