2012-03-26 2 views
0

Недавно я столкнулся с известной ошибкой JavaScript javascript/jQuery и потратил слишком много времени на ее отладку. Для этого мне нужен более умный путь отладки.
Как отлаживать вопросы синхронизации в Javascript?

В частности, моя проблема заключалась в том, что пользовательские входы должны были вызвать вызов базы данных Mongo, и результаты были отправлены после небольшой математики на отображаемые выходы. Но отображаемые выходы были безумно ошибочными. Однако, как только я добавил точку прерывания FireBug, проблема исчезла. В этот момент я знал, что у меня есть проблема с сроками, но не с тем, как его решить.

Вот те relavant фрагменты кода перед ошибкой:

handleDataCallBack : function(transport) { 
    var response = $.parseJSON(transport); 

    if(!hasErrors) { this.updatePage(response); } 
}, 

accessDatabase : function(){ 
    var params = { ... }; 
    DAL.lookupDatabaseInfo(this.handleCallBackOutputPanel, this, params); 
}, 

calculateValues: function() { 
    // some numerical values were updated on the page 
} 

onDomReady : function() { 
// ... 
    //bind drop-down select change events 
    $('#someDropDown').change(function() { 
     me.accessDatabase(); 
     me.calculateValues(); 
    }); 
} 

Чтобы решить эту проблему, все, что я должен был сделать движение в «calculateValues» метод из onDomReady внутри обратного вызова:

handleDataCallBack : function(transport) { 
    var response = $.parseJSON(transport); 

    this.calculateValues(); 
    if(!hasErrors) { this.updatePage(response); } 
}, 

Проблема заключалась в том, что база данных не ответила до начала расчетов. Конечно, это легко заметить ретроспективно. Но какие методы я могу использовать для отладки асинхронных проблем времени в javascript/jQuery в будущем? Это, по-видимому, вне контекста инструментов IDE. И FireBug не помог. Существуют ли какие-либо инструменты для отслеживания асинхронных проблем веб-разработки? Или, может быть, некоторые проверенные временем методы?

+0

так что в общем, какой поток программы? – Joseph

+0

В общем, поток программы заключается в том, что на веб-странице есть выпадающее меню, которое после выбора нового элемента выполняет вызов базы данных. Этот вызов возвращает ~ 20 поплавков, и эти float используются в методе 'calculateValues' для автоматического отображения 4 вычисленных значений float на странице. (На странице много больше, но это соответствующая часть.) – theJollySin

+0

По общему признанию, мой опыт работы с Javascript ограничен, но однажды я столкнулся с аналогичной проблемой. Решение заключалось в том, чтобы перепроектировать его таким образом, чтобы не было возможности решать проблемы времени. Сделайте это, определив сигналы для завершенных событий и слушателей для этих сигналов. Для этого я использовал общую схему обработки сигналов MochiKit. – Keith

ответ

2

я предполагаю, что ваша проблема вызвана здесь:

$('#someDropDown').change(function() { 
    me.accessDatabase(); 
    me.calculateValues(); 
}); 

этот вопрос в том, что ваши расчеты производятся только сразу после вызова. видя, что вызов БД является асинхронным, вычисление не ждет его. однако вы можете сделать это, используя «обратные вызовы». я вижу, вы пытаетесь его реализовать, и да, это правильно. однако, я нахожу это более элегантным:

calculateValues: function() { 
    // some numerical values were updated on the page 
}, 

//since this is your general callback hander 
//you hand over the return data AND the callbackAfter 
handleDataCallBack: function(transport, callbackAfter) { 
    var response = $.parseJSON(transport); 

    //you may need to use apply, im lost in scoping here 
    callbackAfter(); 
    //or 
    callbackAfter.apply(scope); 

    if (!hasErrors) { 
     this.updatePage(response); 
    } 
}, 

accessDatabase: function(callbackAfter) { 
    var params = {}; 

    //pass callbackAfter to the function, 
    //after this is done, pass it to the handler 
    DAL.lookupDatabaseInfo(this.handleCallBackOutputPanel, this, params, callbackAfter); 
}, 

onDomReady: function() { 
    $('#someDropDown').change(function() { 
     me.accessDatabase(function() { 
      //send over what you want done after. 
      //we'll call it "callbackAfter" for easy tracing 
      me.calculateValues(); 
     }); 
    }); 
}​ 
+0

Спасибо за ваш вклад. Честно говоря, я искал больше техники отладки, чем то, что вы разместили. Но то, что вы разместили, похоже на более разумный способ делать вещи, поэтому я собираюсь реализовать что-то очень похожее. Это очень удобно. Благодарю вас. – theJollySin

Смежные вопросы