Ответ 1
Ваша проблема может быть упрощена:
/*1.*/ var fourmTabs = [];
/*2.*/ chrome.tabs.query({}, function(tabs) {
/*3.*/ fourmTabs[0] = tabs[0];
/*4.*/ });
/*5.*/ console.log(fourmTabs[0]);
Вы ожидаете, что массив fourmTabs
будет обновлен (по строке 3), когда будет достигнута линия 5.
Это неверно, потому что метод chrome.tabs.query
асинхронный.
В попытке понять значение асинхронного аспекта я покажу фрагмент кода с той же структурой, что и ваш код и.
/*1.*/ var rope = null;
/*2.*/ requestRope(function(receivedRope) {
/*3.*/ rope = receivedRope;
/*4.*/ });
/*5.*/ grab(rope);
- В строке 1 объявляется наличие веревки.
- В строках 2-4 создается функция обратного вызова, которая должна быть вызвана функцией
requestRope
. - В строке 5 вы собираетесь захватить веревку с помощью функции
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>
С точками останова ваш код работает, потому что к моменту достижения второй части кода обратный вызов уже вызван.