2

chrome.downloads.downloadAPIを使用するChrome拡張機能に取り組んでいます。私の拡張機能は、ダウンロード イベントをキャプチャしてトリガーすることwebkitNotificationです。Google のサンプルの 1 つから、変更の主な作業機能を投稿します。

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 に答える