2

我正在开发一个使用chrome.downloads.downloadAPI 的 chrome 扩展。我的扩展是捕获下载事件并触发webkitNotification。我从谷歌的一个示例中发布了我修改的主要工作功能。

function downloadCheckedLinks() {
    for (var i = 0; i < visibleLinks.length; ++i) {
        if (document.getElementById('check' + i).checked) {         
            chrome.downloads.download({url: visibleLinks[i]}, function(id) {
                var notification = window.webkitNotifications.createNotification('',
                               'OMG', 'hello within for loop, succeed!');
                notification.show();
            });
            alert("function executed!");
        }
    }
    window.close();
}

问题是当我删除 时alert("function executed"),它只在调试模式下工作,我在 for 循环中设置了一个断点并单步执行代码。在正常模式下,我必须添加一些东西才能使其工作(即alert())。我觉得是因为chrome.downloads.download().

由于我对 Web 开发这个词不熟悉,所以我不完全知道我的问题出在哪里。谁能帮我弄清楚这里发生了什么?如果可能的话,你能教我在这样的异步函数调用中chrome.downloads.download(),当匿名回调函数被准确调用吗?

4

2 回答 2

2

评论window.close()可以工作。我猜当窗口关闭时,下载调用被取消。但我不能给出确切的原因。

于 2012-10-28T09:04:25.660 回答
0

您的 javascript 代码在文档的上下文中执行。如果您发出 window.close 您的 javascript 函数将停止并且它的代码和数据垃圾收集。由于回调函数,chrome.downloads.download 可能是异步的。Javascript 引擎是单线程的。因此,只要您的 for 循环正在执行,就没有其他 javascript 正在运行。对 chrome.downloads.download 的调用排队到一些内部 javascript 引擎队列:在当前函数结束后立即执行。您发出的最后一条语句是 window.close();

javascript 队列仍然包含一些要执行的函数,但是 window.close() 获胜:队列被杀死,你的回调永远不会被触发。

它在您使用调试器时起作用:调试器保持您的窗口被引用并因此在内存中,这使 javascript 引擎能够执行排队的函数。

如果您在代码中添加几行,如果所有下载都已结束,您可以关闭窗口:

function downloadCheckedLinks() {
    var pending = 0; // closure var
    for (var i = 0; i < visibleLinks.length; ++i) {
        if (document.getElementById('check' + i).checked) {
            pending = pending + 1;       
            chrome.downloads.download({url: visibleLinks[i]}, function(id) {
                var notification = window.webkitNotifications.createNotification('',
                               'OMG', 'hello within for loop, succeed!');
                notification.show();
                pending = pending - 1;
                if (pending <1) {
                   window.close();
                }
            });
        }
    }
}
于 2012-10-28T13:52:22.060 回答