javascript嵌套函数和变量

时间:2012-01-24 13:35:56

标签: javascript nested

function GetMe(id) {

DB.transaction(
    function (transaction) {

        transaction.executeSql("SELECT * FROM users WHERE id = ?", [id], function (transaction, results) {

            if(results.rows.length > 0) {

                var row = results.rows.item(0);

                return row.name;


            }

        }, errorHandler);
    }
);

}

alert(GetMe(1)); // id 5 exists in users table and alert shows empty

以上代码剂量工作,所以我尝试了下面的代码

function GetMe(id) {

var retval;

DB.transaction(
    function (transaction) {

        transaction.executeSql("SELECT * FROM users WHERE id = ?", [id], function (transaction, results) {

            if(results.rows.length > 0) {

                var row = results.rows.item(0);

                retval = row.name;
                //alert('IN ' + retval); //works

            }

        }, errorHandler);
    }
);

//alert('OUT ' + retval); // undefined

return retval;  // undefined

}

alert(GetMe(1));  // undefined

上面的代码应该可以正常工作,但是我不知道它有什么问题,我几乎尝试了一切

有人可以告诉我什么是错的,并帮我解决这个问题:)

2 个答案:

答案 0 :(得分:1)

这看起来像是因为DB.transaction 异步。您需要做的是将回复function传递给GetMe() function,例如

GetMe(1, function (data) {

});

然后按如下方式修改GetMe

function GetMe(id, callback) {
    DB.transaction(function (transaction) {
        transaction.executeSql("SELECT * FROM users WHERE id = ?", [id], function (transaction, results) {
            if(results.rows.length > 0) {
                var row = results.rows.item(0);
                callback.call(null, row.name);
            }
        }, errorHandler);
    });
}

答案 1 :(得分:0)

问题不在于嵌套函数,事实是内部函数(传递给transaction.executeSql的函数)在你认为它时没有执行。序列更像如下:

  1. GetMe运行
  2. 调用DB.transaction并在
  3. 中传递回调
  4. DB.transaction返回
  5. GetMe返回(无)
  6. 第一个回调是在稍后的某个未知点执行的
  7. 然后调用
  8. executeSql,并在
  9. 中传递另一个回调
  10. executeSQL返回
  11. 回调返回(无)
  12. 然后执行第二个回调(一旦SQL运行),然后返回row.name,但是没有任何内容,其余的程序已经记录了日志。
  13. Tl; dr:您应该调用另一个声明的函数而不是传入回调:

    // inside GetMe
    transaction.executeSql("SELECT * FROM users WHERE id = ?", [id], GotMe);
    
    // outside, in the same scope as GetMe
    function GotMe(transaction, results) {
        // do your stuff here
    }