Фоновые задачи в JavaScript, которые не мешают взаимодействию пользовательского интерфейса - PullRequest
2 голосов
/ 17 ноября 2011

Я работаю над мобильным приложением, реализованным на JavaScript, которое должно выполнять множество фоновых задач - в основном получать данные с сервера (через JSONP) и записывать их в базу данных с использованием локального хранилища. На переднем плане пользователь может перемещаться по локально сохраненным данным и, таким образом, хочет плавно реагирующее приложение.

Это взаимодействие (выборка данных с сервера через JSONP и после некоторой незначительной работы с ним, сохранение их в локальной базе данных) выполняется асинхронно, но из-за необходимых манипуляций DOM для JSONP и взаимодействия с базой данных я не могу эта работа с WebWorkers. Таким образом, я столкнулся с проблемой блокирования очереди событий JavaScript с большим количеством «запросов на фоновую обработку», и приложение реагирует очень медленно (или даже полностью блокируется).

Вот небольшой пример того, как я делаю фоновые вещи:

    var pendingTasksOnNewObjects = new Object();

    //add callbacks to queue
    function addTaskToQueue(id, callback) {
        if (!pendingTasksOnNewObjects[id]) {
            pendingTasksOnNewObjects[id] = new Array();
        }
        pendingTasksOnNewObjects[id].push(callback);
    }

    // example for this pending tasks:
    var myExampleTask = function () {
        this.run = function(jsonObject) {
            // do intersting stuff here as early as a specific new object arrives
            // i.e. update some elements in the DOM to respect the newly arrived object
        };
    };
    addTaskToQueue("id12345", myExampleTask);

    // method to fetch documents from the server via JSONP
    function getDocuments(idsAsCommaSeparatedString) {
        var elem;
        elem = document.createElement("script");
        elem.setAttribute("type", "text/javascript");
        elem.setAttribute("src", "http://serverurl/servlet/myServlet/documents/"+idsAsCommaSeparatedString);
        document.head.appendChild(elem);
    }

    // "callback" method that is used in the JSONP result to process the data
    function locallyStoreDocuments(jsonArray) {
        var i;
        for (i=0; i<jsonArray.length; i++) {
            var obj = jsonArray[i];
            storeObjectInDatabase(obj);
            runTasks(obj.docID, obj);
        }
        return true;
    }

    // process tasks when new object arrives
    function runTasks(id, jsonObject) {
        if(pendingTasksOnNewObjects[id]) {
            while(pendingTasksOnNewObjects[id][0]) {
                pendingTasksOnNewObjects[id][0].run(jsonObject);
                pendingTasksOnNewObjects[id].shift();
            }
        }
        return true;
    }

Я уже смотрел вокруг, читая некоторые вещи о механизмах обработки событий в JavaScript (например, Описание работы Джона Ресигса с таймерами ), но я действительно хочу сделать следующее: проверить, есть ли что-то делать в очереди событий. Если это так, подождите 100 мс и проверьте снова. Если в очереди в данный момент ничего не ожидается, обработайте небольшое количество данных и проверьте снова.

Насколько я прочитал, это невозможно, поскольку JavaScript не имеет прямого доступа к очереди событий.

Так есть ли какие-нибудь идеи по поводу того, как оптимизировать мой код, чтобы приблизиться к цели не мешать событиям пользовательского интерфейса, чтобы дать пользователю плавное взаимодействие с приложением?

1 Ответ

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

Web Workers, похоже, доступны в iOS 5, http://caniuse.com/webworkers

...