Взаимозависимые обратные вызовы в программировании webOS - PullRequest
1 голос
/ 29 января 2010

Это концептуальный вопрос.

Многие операции, выполняемые в webOS, являются асинхронными. Я уже занимался Ajax-программированием, но кажется, что webOS выводит его на новый уровень. Возьмем следующий пример приложения, которое получает список новостных статей из Интернета, а также кэширует статьи локально в базе данных хранения HTML5:

function FirstAssistant() {
}

FirstAssistant.prototype.setup = function() {
    this.controller.setupWidget('articleList',
        this.attributes = { itemTemplate: "article" },
        this.model = {}
    );

    this.db = openDatabase("FooArticles", "1.0");
};

FirstAssistant.prototype.activate = function() {
    this.db.transaction(function(transaction){
        transaction.executeSql(
            "CREATE TABLE IF NOT EXISTS 'articles' (name TEXT, favorite INTEGER DEFAULT 0)",
            [], this.successHandler.bind(this), this.errorHandler.bind(this)
        );
    });

   this.fetchArticles();
};

FirstAssistant.prototype.successHandler = function(transaction, results) {
    // SELECT from 'articles' to populate this.model
};

FirstAssistant.prototype.errorHandler = function(transaction, results) {
    // whatever
};

FirstAssistant.prototype.fetchArticles = function() {
    var request = new Ajax.Request(url, {
        method: 'get',
        onSuccess: this.fetchArticlesSuccess.bind(this),
        onError: this.fetchArticlesError.bind(this)
    });
};

FirstAssistant.prototype.fetchArticlesSuccess = function(request) {
    // populate this.model with new articles
};

FirstAssistant.prototype.fetchArticlesError = function(request) {
    // whatever
};

Итак, поскольку все асинхронно, мы пытаемся создать базу данных и читать кэшированные статьи, в то время как мы загружаем новые статьи из Интернета. Поскольку все делается с помощью обратных вызовов, я не уверен в том, что произойдет первым. База данных знает, какие статьи были помечены как «Избранное», но в зависимости от скорости выполнения this.model может быть пустым (потому что обратный вызов db выполняется первым) или может содержать элементы (потому что AJAX возвращался первым). Таким образом, каждый обратный вызов должен иметь возможность заполнять список или выполнять итерацию списка и выполнять обновления.

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

Чтобы сжать это в вопросы:

  1. JavaScript асинхронный, но есть только один поток выполнения? Нужно ли беспокоиться о двух функциях, редактирующих this.model одновременно?
  2. Каковы некоторые распространенные способы работы с взаимозависимыми асинхронными операциями? (т.е. предотвращение дублирования в this.model, где два источника могут иметь перекрывающиеся данные для модели)

Ответы [ 2 ]

2 голосов
/ 02 февраля 2010

В качестве ответа на мой собственный вопрос я теперь вижу Mojo.Function.Synchronize :

Экземпляры этого класса используются для обеспечения одновременного вызова набора функций обратного вызова. После создания используйте метод wrap (), чтобы обернуть любые обратные вызовы, которые вы хотите синхронизировать, прежде чем передавать их асинхронной службе. Объект синхронизации будет откладывать вызов любого из них до тех пор, пока не будут вызваны все возвращенные оболочки.

1 голос
/ 02 февраля 2010

Если вы явно не используете рабочие потоки , что-то добавленное в последние браузеры и механизмы JS, обратные вызовы Javascript не будут выполняться одновременно.

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

...