Google Chromeの拡張機能を作成(学習)しています。
一部のコードをデバッグするために、次のようにconsole.log()
を挿入しました。
var fourmTabs = new Array();
chrome.tabs.query({}, function (tabs) {
for (var i = 0; i < tabs.length; i++) {
fourmTabs[i] = tabs[i];
}
});
for (var i = 0; i < fourmTabs.length; i++) {
if (fourmTabs[i] != null)
window.console.log(fourmTabs[i].url);
else {
window.console.log("??" + i);
}
}
これは非常に単純なコードです。すべてのタブ情報を独自の配列に取得し、いくつかのものを出力します。
コードが正常に機能するかどうかを確認するために、コードを実行します。ここに問題があります:
理由は何ですか?
問題は次のように単純化できます。
/*1.*/ var fourmTabs = [];
/*2.*/ chrome.tabs.query({}, function(tabs) {
/*3.*/ fourmTabs[0] = tabs[0];
/*4.*/ });
/*5.*/ console.log(fourmTabs[0]);
5行目に到達すると、fourmTabs
配列が(3行目で)更新されることが期待されます。
それは間違ったです。なぜならchrome.tabs.query
メソッドは非同期です。
非同期の側面の重要性を理解してもらうために、コードと同じ構造のコードスニペットを示しますおよびストーリー。
/*1.*/ var rope = null;
/*2.*/ requestRope(function(receivedRope) {
/*3.*/ rope = receivedRope;
/*4.*/ });
/*5.*/ grab(rope);
requestRope
関数によって呼び出される必要があります。grab
関数を使用してロープをつかみます。requestRope
が実装されている場合同期的に、問題はありません:
あなた:「こんにちは、ロープが欲しいです。ロープを投げてください「コールバック関数を呼び出す」 持っているとき」
彼女:「もちろん」 ロープを投げる
あなた:ロープをジャンプしてつかむ-あなたはなんとか反対側に着くことができます、生きている。
requestRope
が実装されている場合非同期、同期として扱うと問題が発生する可能性があります。
あなた:「私にロープを投げてください。」
彼女:「もちろん。見てみましょう...」
あなた:ジャンプしてロープをつかもうとしますロープがないので、倒れて死にます。
彼女:ロープを投げる もちろん、遅すぎます。
非同期実装関数と同期実装関数の違いを確認したので、元の質問を解決しましょう。
var fourmTabs = new Array();
chrome.tabs.query({}, function (tabs) {
for (var i = 0; i < tabs.length; i++) {
fourmTabs[i] = tabs[i];
}
// Moved code inside the callback handler
for (var i = 0; i < fourmTabs.length; i++) {
if (fourmTabs[i] != null)
window.console.log(fourmTabs[i].url);
else {
window.console.log("??" + i);
}
}
});
// <moved code inside callback function of chrome.tabs.query>
ブレークポイントを使用すると、コードは機能します。これは、コードの2番目の部分に到達するまでに、コールバックがすでに呼び出されているためです。