异步回调很棒,但是当一个回调取决于另一个回调的结果时,我会回调带有回调的api调用,等等。
apiCall(function () { apiCall(function () { apiCall(function () ...
我可以命名回调函数,而不是将它们包含在内。这看起来更漂亮,嵌套更少,但我觉得它更容易阅读。
这是一个例子。我需要查询本地sqlite数据库,使用结果查询服务器,然后使用响应来更新本地数据库。
function sync() {
db.transaction(
function (transaction) {
execute(transaction, 'SELECT max(server_time) AS server_time FROM syncs;', [],
function (transaction, results) { // Query results callback
var t = results.rows.item(0).server_time;
$.post('sync.json', { last_sync_time: (t || '1980-01-01') },
function (data) { // Ajax callback
db.transaction(
function(transaction) {
$(data.thing).each(function () {
var thing = new Thing(this.thing);
thing.insert(transaction);
});
});
});
});
});
}
有没有办法解开这个(除了命名回调)?
答案 0 :(得分:0)
我认为你通过命名函数而不是内联函数来放弃非嵌套的东西太快了。这几乎是清除这一混乱的唯一方法。
而不是:
do_a(
function () {
// more nesting...
}
);
使用名称为每个功能提供一些清晰度和目的:
function on_a_complete() {
}
do_a(on_a_complete);
答案 1 :(得分:0)
我想你回答了自己的问题。命名你的回调实际上是解决这个问题的唯一方法。类似的东西:
execute(transaction, 'SELECT max(server_time) AS server_time FROM syncs;', [],handleLocalResults, errorHandler);
handleLocalResults = function (transaction, results)...
handleServerResults = func...
答案 2 :(得分:0)
命名回调是你可以做的一件事,但你需要做的另一件事是拥有非重叠的SQL事务。 (1)
您的第一笔交易应该是这样的:
// The whole thing starts here
db.transaction(selectTimeCB, null, ajaxPost);
事务以回调开始以选择时间,当事务完成时,调用ajaxPost操作。
// Initial transaction to get server_time
var selectTimeCB = function(t) {
var query = 'SELECT max(server_time) AS server_time FROM syncs';
t.executeSql(query, [], postLastSyncCB);
};
// This saves the results from the above select, and nothing else.
var server_time;
var postLastSyncCB = function(t, results) {
server_time = results.rows.item(0).server_time;
};
var ajaxPost = function() {
$.post('sync.json', { last_sync_time: (server_time || '1980-01-01') }, nextDbTransaction);
};
如果您有重叠的SQL事务,那可能会破坏数据库的性能。我最近在一个有500多行的数据库上测试了200个混合事务,发现保持事务分离可以将运行时间缩短90秒到3-5秒。