2013-08-07 3 views
0

Я не понимаю что-то с обратным вызовом javascript. Я хотел бы сделать что-то вроде DAO на Java, где я управляю своими данными, а затем вызываю объект DAO в своем контроллере. Но в JavaScript У меня есть что-то вроде этого:javascript не может отделить вид от данных

DAO

function DAO() { 
    this.getData = function(arg1, arg2, callbackSuccess, callbackError) { 
     var data = null; 

     // do something to get data. If ok then call callbackSuccess 
     callbackSuccess(data); 
    } 

    var callbackSuccess = function(data) { 
     // HERE I HAVE THE DATA. HOW TO RETURN IT TO <DATA> ? 
    } 

    var callbackError = function(data) { 
     // ERROR 
    } 
} 

Где-то еще, где мне нужно получить данные ...

var dao = new DAO(); 
var <DATA> = dao.getData(var1, var2, callbackSuccess, callbackError); 

я, вероятно, может поставить обратный вызов в мой контроллер и отправить их метод getData, но это кажется мне странным ...

ответ

0

Вам нужно понять разницу между синхронным и асинхронным кодом.

В синхронном коде каждое выполняемое вами утверждение оценивается и его результат возвращается вам. Никакая другая инструкция не оценивается до тех пор, пока вы не закончите оценку текущего оператора. Таким образом, утверждения всегда оцениваются по порядку.

var a = syncStatement1(); 
var b = syncStatement2(); 
console.log("finished!!!"); 

В приведенном выше коде syncStatement2() никогда не будет оцениваться, прежде чем syncStatement1(). И журнал «закончен !!!» будет напечатано только после завершения всего кода в двух предыдущих функциях.

В асинхронном коде, однако, порядок выполнения отличается. Когда вы запрашиваете асинхронный оператор для оценки, механизм выполнения просто назначает его для оценки в какой-то момент позже и продолжает выполнение вашей программы.

var a = asyncStatement1(); 
var b = asyncStatement2(); 
console.log("finished???"); 

В этом втором примере выше, исполнительный механизм не будет ждать, пока каждая функция оператор оценить перед выполнением следующего оператора. К тому времени, когда вы доберетесь до линии ведения журнала, говорящей «закончено ???» вы не можете быть уверены, что предыдущие функции завершили выполнение.

Механизм выполнения просто назначил их на исполнение, и в какой-то момент он выполнит их и «вернет» все, что они вернут, но этого не произошло, когда вы изначально вызывают их.

Это имеет несколько последствий, во-первых, вы не можете запросить результат асинхронной функции, такой как a = asyncFunc(), потому что должно быть значение a, если функция еще не запущена ?. Скорее всего, undefined, так как пока нет результата. Однако в зависимости от того, как вы создаете асинхронную функцию, вы можете вернуть объект обещания, который вы также можете использовать для отмены асинхронного действия или позже спросить, есть ли доступный результат.

Вторая причина в том, что, поскольку код будет выполняться позже, в контексте, который у вас нет никакого контроля, единственный способ узнать, что произошло, - попросить функцию сам сообщить вам о результатах, а это почему вы вынуждены регистрировать обратные вызовы с асинхронными функциями, как:

function asyncFunc(args, success, error) { 
    //do something here 
    if(success) success(data); 
} 

Там нет никакого способа обойти это и делать вид, код на самом деле работает в синхронном режиме. Вы вынуждены менять то, как вы думаете.

Как я уже говорил выше, в зависимости от структуры, которую вы используете, вы можете получить обещание от вашей асинхронной функции и изменить вещи немного, чтобы выглядеть немного лучше, так как в:

var promise = asynchFunc(args); 
promise.success(function(data) { 
    //do something with data when successful in async. 
}); 

promise.error(function(error){ 
    //handle the error that happened in async. 
}); 
console.log("Most likely not finished yet!!!"); 

Но это все еще асинхронное выполнение, и к тому моменту, когда вы достигнете журнала, вы, скорее всего, еще не обработали какой-либо обратный вызов.

Некоторые сторонние библиотеки, такие как async, могут сделать вашу жизнь немного проще при работе с этим типом кода, если вы хотите дать им некоторое соображение.

Наконец, чтобы решить ваш вопрос, вы не можете сделать это

var dao = new DAO(); 
var <DATA> = dao.getData(var1, var2, callbackSuccess, callbackError); 

Но вы могли бы сделать это:

var <DATA> = null; 
function onSuccess(data){ 
    //act on your data and update controller 
    <DATA> = data; 
} 

function onError(error){ 
    //handle error 
} 

dao.getData(var1, var2, onSuccess, onError);