我对javascript回调不了解。我想做一些像Java中的DAO,我操纵我的数据,然后在我的控制器中调用DAO对象。但是在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 :(得分:0)
您需要了解同步和异步代码之间的区别。
在同步代码中,将对您执行的每个语句进行评估,并将结果返回给您。在完成对当前语句的评估之前,不会评估其他语句。因此,语句总是按顺序进行评估。
var a = syncStatement1();
var b = syncStatement2();
console.log("finished!!!");
在上面的代码中syncStatement2()
永远不会在syncStatement1()
之前进行评估。日志“完成!!!”只有在完成前两个功能中的所有代码时才会打印。
但是,在异步代码中,执行顺序是不同的。当您要求评估异步语句时,执行引擎会在稍后的某个时间点安排它进行评估并继续执行您的程序。
var a = asyncStatement1();
var b = asyncStatement2();
console.log("finished???");
在上面的第二个示例中,执行引擎不会等待每个语句函数在执行下一个语句之前进行求值。当你到达记录行说“完成???”你不能确定以前的功能已经完成了。
执行引擎只是简单地安排它们执行,并且在某些时候它会执行它们并“返回”它们返回的任何内容,但是当你最初调用它们时就不会发生这种情况。
这有几个含义,第一个是你不能要求像a = asyncFunc()
之类的异步函数的结果,因为如果函数还没有运行,那么a
的值应该是什么?很可能是未定义的,因为还没有可用的结果。但是,根据您创建异步函数的方式,您可能会返回一个promise对象,您也可以使用它来取消异步操作,或者稍后询问是否有可用的结果。
第二个含义是,由于代码将在稍后执行,在上下文中你无法控制,知道发生了什么的唯一方法是通过要求函数本身通知你结果,这就是为什么您被迫使用异步函数注册回调,例如:
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);