0

正常に動作する次の(簡略化された)例を検討してください。

var tabs = window.gBrowser.tabs;
for (var i = 2, len = tabs.length; i < len; i++) {
  var uri = window.gBrowser.getBrowserAtIndex(i).currentURI.spec;
}

以下は、最後のタブでメッセージwindow.gBrowser.getBrowserAtIndex(...) is undefinedで失敗することがあります

var tabs = window.gBrowser.tabs;
for (var i = 2, len = tabs.length; i < len; i++) {
  var uri = window.gBrowser.getBrowserAtIndex(i).currentURI.spec;
  window.gBrowser.removeTab(window.gBrowser.tabContainer.childNodes[i]);
}

失敗する理由と、常にではなく時々失敗する理由がわかりません。

gBrowser.getBrowserAtIndex(i)タブの URL を取得する代わりに使用できる他の方法はありますか?

4

2 に答える 2

1

最初の数のタブを保存したループ内でタブを閉じてlen = tabs.lengthから、既存のタブの数がアクションによって変更された可能性があるときに、元のタブの数と比較しているようです。

コンストラクト:は、 の長さが変化しない
for (let i = 2, len = tabs.length; i < len; i++) {...}
条件下でより効率的です。tabsただし、この場合、タブの数を変更しているtabs.lengthため、このループの終了条件を確認するたびに比較する必要があります。実際
for (let i = 2, len = tabs.length; i < len; i++) {...}
、現在のループが常に失敗するとは限らない唯一の理由window.gBrowser.removeTab()は、タブが実際に削除される前に戻っていることです。タブが実際に削除される前にループを完了するかどうかを競っています。

ただし、問題はそれだけではありません。現在インデックスされているタブを削除しようとしています。ほとんどの配列と同様に、タブが削除された場合、ほとんどの条件下で、残りのより高いインデックスのタブは、既に操作しているインデックスになるように下にシフトされます。現在のループが定期的に他のすべてのタブをスキップしない唯一の理由は、window.gBrowser.removeTab()現在インデックス付けされているタブを実際に削除する前にループが戻ることです。エラーが表示されている場合にのみ、実際にタブをスキップしますundefined

ループは実際には次のようになります。
for (let i = tabs.length - 1; i >=2; i--) {...}
このように、リストの最後から開始して、そこから削除します。これにより、undefinedタブが実際に削除される前にプロセス全体を完了する必要があるという競合状態を排除することで、問題とタブをスキップする可能性の両方を防ぎます。

于 2014-10-06T08:55:57.257 に答える