我正在开发一个用JavaScript实现的移动应用程序,它必须做很多后台工作——主要是从服务器(通过JSONP)获取数据,并使用本地存储将其写入数据库。在前台,用户可能会浏览本地存储的数据,因此希望应用程序反应流畅。
这种交互(通过JSONP从服务器获取数据,并在做了一些小的工作后,将其存储在本地数据库中)是异步完成的,但由于JSONP和数据库交互的必要DOM操作,我无法与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中事件处理机制的东西(例如John Resigs对使用计时器的描述),但我真正想做的是:检查事件队列中是否有事情要做。如果是,等待100ms后再次检查。如果当前队列中没有等待,则处理少量数据并再次检查。
据我所知,这是不可能的,因为JavaScript没有直接访问事件队列。
那么,是否有任何设计思路,如何优化我的代码,以更接近目标,不干扰UI事件,给用户一个顺利的应用程序交互?
Web Workers似乎在iOS 5中可用,http://caniuse.com/webworkers