1

这是一个概念问题。

webOS 中发生的许多操作都是异步的。我以前做过Ajax编程,但感觉webOS把它带到了一个新的高度。以下面的应用程序示例为例,该应用程序从 Web 检索新闻文章列表,并将文章本地缓存在 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 中的重复,其中两个源可能具有模型的重叠数据)
4

2 回答 2

2

作为对我自己问题的回答,我现在看到Mojo.Function.Synchronize

此类的实例用于确保同时调用一组回调函数。创建后,使用 wrap() 方法包装您希望同步的任何回调,然后再将它们传递给异步服务。同步对象将推迟调用它们中的任何一个,直到调用了所有返回的包装器。

于 2010-02-02T11:58:09.013 回答
1

除非您明确使用工作线程(添加到最近的浏览器和 JS 引擎中的东西),否则不会同时执行 Javascript 回调。

一种常见的技术是使用一组标志——如果一个操作取决于要完成的五件事,则将一个标志设置为 5,每完成一项就将其减一,然后检查每件事是否为零,然后如果是这样,请运行一个终结方法,该方法对所有收集的数据执行操作。

于 2010-02-01T21:02:46.293 回答