您需要了解同步代码和异步代码之间的区别。
在同步代码中,您执行的每条语句都会被评估并将其结果返回给您。在您完成对当前语句的评估之前,不会评估其他语句。因此,语句总是按顺序进行评估。
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);