【问题标题】:getting data from async function从异步函数获取数据
【发布时间】:2011-12-07 03:06:57
【问题描述】:

我有这个代码:

    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 异步工作,但我使用回调来返回数据。有人可以解释为什么它不起作用以及如何解决这个问题吗?

【问题讨论】:

    标签: javascript asynchronous web-sql


    【解决方案1】:

    执行此操作的标准方法是包含您自己的回调,如下所示:

    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 */
    });
    

    【讨论】:

    • 那么,有没有办法将该数组放在异步函数外部的变量中?
    • @nukl:您可以将值分配给任何更高范围的变量(例如全局变量),但这对您没有帮助。使用回调的重点是何时访问数据。如果您在执行回调之前访问变量(并设置了值),您会得到错误的数据或没有数据。将响应分配给回调之外的其他变量有完全有效的用例,但您必须了解进行异步调用的含义。
    • @nukl,除非你想使用 CoffeeScript(一种 to-javascript 编译语言):jashkenas.github.com/coffee-script
    • 谢谢,知道了。顺便说一句,@Ben Lee,callback(returnData(q)); 需要改为callback(q),对吧?
    • @nukl,这取决于你想要什么。我假设“returnData”是一个在将结果传递回回调之前对结果进行更多后处理的函数。但如果 returnData 不是必需的,那么你可以做callback(q)。这取决于您的需求。
    【解决方案2】:

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

    在您的代码中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;
    });
    

    【讨论】:

      猜你喜欢
      • 2019-04-25
      • 2019-07-29
      • 2021-08-27
      • 2020-06-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-03-18
      相关资源
      最近更新 更多