После вызова chrome.tabs.query результаты недоступны.

Я создаю (учит) расширение для 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

Ваша проблема может быть упрощена:

/*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>

С точками останова ваш код работает, потому что к моменту достижения второй части кода обратный вызов уже вызван.