Новое в асинхронном программировании на JavaScript.Любой совет? - PullRequest
2 голосов
/ 17 февраля 2011

Асинхронные обратные вызовы хороши, но когда один обратный вызов зависит от результата другого, у меня возникают обратные вызовы с вызовами API, которые имеют обратные вызовы и т. Д.в соответствии.Это выглядит красивее и меньше вложенности, но мне не легче читать.

Вот пример.Мне нужно запросить локальную базу данных 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);
                            });
               });
           });
      });
});
}

Есть ли способ отменить это (кроме именования обратных вызовов)

Ответы [ 3 ]

0 голосов
/ 17 февраля 2011

Я думаю, что вы ответили на свой вопрос.Назвать ваши обратные вызовы - действительно единственный способ убрать это.Что-то вроде:

execute(transaction, 'SELECT max(server_time) AS server_time FROM syncs;', [],handleLocalResults, errorHandler);

handleLocalResults = function (transaction, results)...

handleServerResults = func... 
0 голосов
/ 14 октября 2013

Именование обратных вызовов - это одна вещь, которую вы можете сделать, но другая вещь, которую вам нужно сделать, это иметь непересекающиеся транзакции 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, это может реально снизить производительность базы данных.Недавно я проверил 200 смешанных транзакций в базе данных с чуть более 500 строками и обнаружил, что разделение транзакций сократило время выполнения с 90 до 3-5 секунд.

0 голосов
/ 17 февраля 2011

Я думаю, что вы слишком быстро отбрасываете не вложенные объекты, называя свои функции вместо того, чтобы писать их встроенными.Это в значительной степени единственный способ убрать этот беспорядок.

Вместо:

do_a(
  function () {
    // more nesting...
  }
);

Используйте имена, чтобы придать немного ясности и цели каждой функции:

function on_a_complete() {

}

do_a(on_a_complete);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...