Javascript 从异步函数获取数据

Javascript 从异步函数获取数据,javascript,asynchronous,web-sql,Javascript,Asynchronous,Web Sql,我有以下代码: function getData(){ db.transaction(function(tx){ tx.executeSql('SELECT * from q', [], function(tx, result){ var q = []; for (var i=0; i < result.rows.length; i++) {

我有以下代码:

    function getData(){
        db.transaction(function(tx){
            tx.executeSql('SELECT * from q', [], function(tx, result){
                var q = [];
                for (var i=0; i < result.rows.length; i++) {
                    q.push(result.rows.item(i));
                };
                console.log(q.length);  // 3
                returnData(q);
            });
        });
    }

    function returnData(data){
        console.log(data.length); // 3
        return data;
    }

   var q = getData(); // undefined

而且它没有像预期的那样工作,它没有返回任何东西。假设发生了这种情况,因为db.transaction是异步工作的,但我使用回调返回数据。有人能解释一下它为什么不起作用以及如何修复吗?

标准的方法是包含您自己的回调,如下所示:

function getData(callback){
    db.transaction(function(tx){
        tx.executeSql('SELECT * from q', [], function(tx, result){
            var q = [];
            for (var i=0; i < result.rows.length; i++) {
                q.push(result.rows.item(i));
            };
            console.log(q.length);  // 3
            callback(returnData(q));
        });
    });
}

function returnData(data){
    console.log(data.length); // 3
    return data;
}

getData(function(q) {
    /* do something with q */
});

您不会返回任何异步操作的结果,而是侦听它

在您的代码中,returnData确实返回数据,但是如果您不对结果执行任何操作,它将被丢弃。相反,您应该使用自己的回调

function getData(callback){
    db.transaction(function(tx){
        tx.executeSql('SELECT * from q', [], function(tx, result){
            var q = [];
            for (var i=0; i < result.rows.length; i++) {
                q.push(result.rows.item(i));
            };
            console.log(q.length);  // 3
            callback(q);
        });
    });
}

var q;
getData(function(data) {
    console.log(data.length); // 3
    console.log(data);
    doStuffWith(data);
    q = data;
});

因此,无法将该数组放入异步函数之外的变量中?@nukl:您可以将值分配给任何更高范围的变量,例如全局变量,但这对您没有帮助。使用回调时,重要的一点是访问数据的时间。如果在执行回调和设置值之前访问变量,则会得到错误或没有数据。将响应分配给回调之外的其他变量有一些非常有效的用例,但是您必须知道进行异步调用的含义。@nukl,除非您想将CoffeeScript a用于javascript编译语言:谢谢,明白了。顺便说一句,@Ben Lee,callbackreturnDataq;需要改为callbackq,对吗?@nukl,这取决于你想要什么。我假设returnData是一个函数,它在将结果传递回回调之前对结果进行了更多的后处理。但如果returnData不是必需的,那么您可以直接执行callbackq。这取决于你的需要。