После вызова 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);
  • На первой линии объявлено о наличии веревки.
  • В строках 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>

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