我是第一次开发附加组件。它在状态栏中放置一个小部件,显示未读的Google阅读器项目数。为了适应这种情况,附加组件流程每分钟查询Google Reader API并将响应传递给小部件。当我运行cfx test
时,我收到此错误:
错误:页面已被破坏,无法再使用。
我确保捕获小部件的detach
事件并停止刷新计时器作为响应,但我仍然看到错误。我究竟做错了什么?这是相关代码:
// main.js - Main entry point
const tabs = require('tabs');
const widgets = require('widget');
const data = require('self').data;
const timers = require("timers");
const Request = require("request").Request;
function refreshUnreadCount() {
// Put in Google Reader API request
Request({
url: "https://www.google.com/reader/api/0/unread-count?output=json",
onComplete: function(response) {
// Ignore response if we encountered a 404 (e.g. user isn't logged in)
// or a different HTTP error.
// TODO: Can I make this work when third-party cookies are disabled?
if (response.status == 200) {
monitorWidget.postMessage(response.json);
} else {
monitorWidget.postMessage(null);
}
}
}).get();
}
var monitorWidget = widgets.Widget({
// Mandatory widget ID string
id: "greader-monitor",
// A required string description of the widget used for
// accessibility, title bars, and error reporting.
label: "GReader Monitor",
contentURL: data.url("widget.html"),
contentScriptFile: [data.url("jquery-1.7.2.min.js"), data.url("widget.js")],
onClick: function() {
// Open Google Reader when the widget is clicked.
tabs.open("https://www.google.com/reader/view/");
},
onAttach: function(worker) {
// If the widget's inner width changes, reflect that in the GUI
worker.port.on("widthReported", function(newWidth) {
worker.width = newWidth;
});
var refreshTimer = timers.setInterval(refreshUnreadCount, 60000);
// If the monitor widget is destroyed, make sure the timer gets cancelled.
worker.on("detach", function() {
timers.clearInterval(refreshTimer);
});
refreshUnreadCount();
}
});
// widget.js - Status bar widget script
// Every so often, we'll receive the updated item feed. It's our job
// to parse it.
self.on("message", function(json) {
if (json == null) {
$("span#counter").attr("class", "");
$("span#counter").text("N/A");
} else {
var newTotal = 0;
for (var item in json.unreadcounts) {
newTotal += json.unreadcounts[item].count;
}
// Since the cumulative reading list count is a separate part of the
// unread count info, we have to divide the total by 2.
newTotal /= 2;
$("span#counter").text(newTotal);
// Update style
if (newTotal > 0)
$("span#counter").attr("class", "newitems");
else
$("span#counter").attr("class", "");
}
// Reports the current width of the widget
self.port.emit("widthReported", $("div#widget").width());
});
修改:我已将项目完整上传至this GitHub repository。
答案 0 :(得分:0)
我想当您在monitorWidget.postMessage()
中致电refreshUnreadCount()
时会出现此消息。明显的原因是:当您确保仅在工作者仍处于活动状态时调用refreshUnreadCount()
时,此函数将执行可能需要一段时间的异步请求。因此,当此请求完成时,工作人员可能已被销毁。
一种解决方案是将worker作为参数传递给refreshUnreadCount()
。然后,它可以添加自己的detach
侦听器(在请求完成时将其删除),如果在执行请求时分离了worker,则忽略响应。
function refreshUnreadCount(worker) {
var detached = false;
function onDetach()
{
detached = true;
}
worker.on("detach", onDetach);
Request({
...
onComplete: function(response) {
worker.removeListener("detach", onDetach);
if (detached)
return; // Nothing to update with out data
...
}
}).get();
}
然后再次使用try..catch
来检测这种情况并抑制错误可能会更简单 - 但不完全是一个干净的解决方案。
答案 1 :(得分:0)
我刚刚在irc上看到了您的消息,感谢您报告您的问题。 您正面临SDK中的一些内部错误。我已经打开了关于here的错误。
您绝对应该保留代码的第一个版本,即向小部件发送消息,即widget.postMessage
(而不是worker.postMessage
)。然后我们将不得不修复我链接的错误,以便让代码正常工作!!
然后我建议你将setInterval移动到顶层,否则你将触发多个间隔和请求,每个窗口一个。每个新的firefox窗口都会触发此attach
事件。
答案 2 :(得分:0)
我认为如果您使用monitorWidget.port.emit("widthReported", response.json);
方法,则可以触发该事件。它是与内容脚本和附加脚本通信的第二种方式。