Доступ к свойствам литералов объекта из обратных вызовов (асинхронные методы) - PullRequest
8 голосов
/ 08 ноября 2011

Я пишу расширение Chrome, которое должно взаимодействовать с поддеревом закладок.Существует много взаимодействий с этим поддеревом, поэтому я абстрагирую эту логику в литерал объекта, например:

var contextStore = {
    'root_id': undefined,
    'setup': function() {...},      // populates root_id
    'add': function(name) {...},    // uses root_id
    'remove': function(name) {...}, // uses root_id
    // ... etc ...
};

contextStore.setup(); // only once.
contextStore.add("foo");
contextStore.add("bar");
// ... etc

Пока все хорошо.

Проблема у меня 'Это вызвано асинхронными API Chrome (и моим отсутствием JS-fu).То есть:

var contextStore = {
    'root_id': undefined,
    'setup': function() {
        chrome.bookmarks.getTree(function(tree) {
           // do some work to find a given folder in bookmarks.
           // now I want to save that folder's id for access in other methods.

           // Fail: 'this' refers to chrome.bookmarks.getTree. 
           this.root_id = computed_thing; // doesn't work!
        });
    }
    // ... etc ...
};

Мой вопрос:

Как мне получить доступ к элементам литерала вмещающего объекта из различных обратных вызовов методов API Chrome?

Iрассмотрел использование шаблона модуля, но, похоже, он ничего не меняет, и не похоже, что этот код будет использоваться чем-либо за пределами расширения.

Ответы [ 2 ]

9 голосов
/ 08 ноября 2011

Вам необходимо сохранить ссылку на this, которая указывает на объект contextStore;

var contextStore = {
    'root_id': undefined,
    'setup': function() {
        var that = this; // Store reference here.

        chrome.bookmarks.getTree(function(tree) { 
           that.root_id = computed_thing; // does work!
        });
    }
    // ... etc ...
};

Это эквивалентно действию;

var contextStore = {
    'root_id': undefined,
    'setup': function() {
        chrome.bookmarks.getTree(function(tree) { 
           contextStore.root_id = computed_thing; // does work!
        });
    }
    // ... etc ...
};

Однако вы получаетепреимущество не повторного использования contextStore везде.

1 голос
/ 08 ноября 2011

Ключевое слово this может быть связано с разными вещами в зависимости от того, как вы его называете.Я не эксперт по javascript, но есть хорошее объяснение на A List Apart .

. Решение заключается в явном связывании при вызове функции с использованием либо my_function.apply(obj, [args]), my_function.call(obj, args)(позвоните сейчас) или предварительно связайте функцию для последующего вызова: my_function.bind(obj).

Будучи явным программистом на python, вы, вероятно, будете счастливы: -)

Ответ Мэтта в конечном итоге тем лучшеподход, поскольку он еще более явный, лаконичен и не требует, чтобы функция вызывалась или готовилась определенным образом.Я просто подумал, что попытаюсь объяснить, что происходит.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...