为什么chrome.downloads.download在没有添加其后的其他函数的情况下不起作用。(在添加alert()后它起作用)

时间:2012-09-10 13:52:31

标签: google-chrome-extension

我正在使用chrome.downloads.download API进行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()的异步函数调用。

由于我是网络开发词的新手,我不知道我的问题在哪里。谁能帮助我弄清楚这里发生了什么?如果可能的话,你可以告诉我,在这个chrome.downloads.download()的异步函数调用中,当完全调用匿名回调函数时吗?

2 个答案:

答案 0 :(得分:2)

评论window.close()可以发挥作用。我想当窗口关闭时,下载调用将被取消。但我不能说出确切的理由。

答案 1 :(得分: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();
                }
            });
        }
    }
}