webOS 编程中相互依赖的回调
这是一个概念性问题。
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 可能为空(因为数据库回调首先执行),或者其中可能有项目(因为 AJAX 首先返回)。因此,每个回调都需要能够填充列表或迭代列表并进行更新。
我当前的项目又增加了一层复杂性,因为我使用 FilterList,添加另一个回调和模型。
将其浓缩为一个问题:
- JavaScript 是异步的,但是只有一个执行线程吗?我需要担心两个函数同时编辑 this.model 吗?
- 处理相互依赖的异步操作有哪些常见方法? (即防止 this.model 中出现重复,其中两个源可能具有重叠的模型数据)
This is a conceptual question.
Many of the operations that happen in webOS are asynchronous. I have done Ajax programming before, but it feels like webOS takes it to a new level. Take the following example of an application that retrieves a list of news articles from the web, and also caches articles locally in an HTML5 storage database:
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
};
So, because everything is asynchronous, we are attempting to create the database and read cached articles while we fetch new articles from the web. Because everything is done via callbacks, I have no confidence in what will happen first. The database knows which articles have been marked as "Favorites," but depending on execution speed this.model may be empty (because the db callback is executing first) or it may have items in it (because the AJAX returned first). So, each callback needs to be able to populate a list or iterate the list and do updates.
My current project adds another layer of complexity because I am using a FilterList, adding another callback and model to the mix.
To condense this into questions:
- JavaScript is asynchronous, but is there only one thread of execution? Do I need to worry about two functions editing this.model at the same time?
- What are some common ways of dealing with interdependent asynchronous operations? (ie. preventing duplication in this.model, where two sources may have overlapping data for the model)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
作为我自己问题的答案,我现在看到 Mojo.Function.Synchronize:
As an answer to my own question, I now see Mojo.Function.Synchronize:
除非您明确使用 工作线程(添加到最新浏览器和 JS 引擎中的内容),否则 Javascript 回调不会不能同时执行。
一种常见的技术是使用一组标志 - 如果某个操作取决于要完成的五件事,则将标志设置为 5,每完成一项就将其减一,并检查每件事以查看它是否为零以及如果是这样,请运行一个最终确定方法,对所有收集到的数据执行该操作。
Unless you explicitly use worker threads, something added to recent browsers and JS engines, Javascript callbacks won't be executed at the same time.
One common technique is to use a set of flags -- if an operation depends on five things to be done, set a flag to 5, decrement it by one with each item that's completed, and have each thing check to see if it's zero and if so, run a finalization method that does the action with all the collected data.