一日程序百日猿

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

js的回调函数还是很有学问的。

情景 nodejs循环读取数据库,回调函数回调的时候里面的index就早就被修改了。纠结了好久

错误代码:

UserPokemonService.getPokemonOfUserCarry = function (connection, userId, callback) {    
    console.log('getPokemon');
    var sql = 'SELECT * FROM user_pokemon WHERE user_id = \'' + userId + '\' and place > 0;';
    var query = connection.query(sql,function(err,pokemonRows) {
        if(err) {
            console.log(this + err.code);
        }
        else {
            var len = pokemonRows.length;
            var todo = len;
            var pokemons = new Object();
            console.log(len);
            if(len > 0) {
                //get move infomations
                for(var i = 0; i < len; i++) {
                    var sqlMove = 'SELECT * FROM MOVES WHERE id = ' + pokemonRows[i]['move1_id']
                    + ' OR id = ' + pokemonRows[i]['move2_id']
                    + ' OR id = ' + pokemonRows[i]['move3_id']
                    + ' OR id = ' + pokemonRows[i]['move4_id'];
                    console.log(sqlMove);
                    console.log(pokemonRows[i]);
                    pokemons[i] = new Object();
                    pokemons[i]['baseinfo'] = pokemonRows[i];
                    connection.query(sqlMove, function(err, moveRows) {
                        console.log(i);
                        if(err) {
                            console.log(this + err.code);
                        }
                        else {
                            //这里的i被修改了。
                            pokemons[i]['moves'] = moveRows;
                            todo --;
                            if(todo == 0) {
                                callback(pokemons);
                            }
                        }
                    });
                }
            }
            else {
                callback(pokemons);
            }
        }
    });
}

 

回调函数里面的i被修改 所以就越界了。

TypeError: Cannot set property 'moves' of undefined

 

解决办法:

http://tech.richardrodger.com/2011/04/21/node-js-%E2%80%93-how-to-write-a-for-loop-with-callbacks/

用callback的最好别for 不然服务器压力大。

UserPokemonService.getPokemonOfUserCarry = function (connection, userId, callback) {    
    console.log('getPokemon');
    var sql = 'SELECT * FROM user_pokemon WHERE user_id = \'' + userId + '\' and place > 0;';
    var query = connection.query(sql,function(err,pokemonRows) {
        if(err) {
            console.log(this + err.code);
        }
        else {
            var len = pokemonRows.length;
            var todo = len;
            console.log(len);
            if(len > 0) {
                //get move infomations
                loadMoveToPokemon(len - 1, pokemonRows, connection, callback);
            }
            else {
                callback(pokemons);
            }
        }
    });
}

function loadMoveToPokemon(todo, userPokemonRows, connection, callback) {
    var sqlMove = 'SELECT * FROM MOVES WHERE id = ' + userPokemonRows[todo]['move1_id']
    + ' OR id = ' + userPokemonRows[todo]['move2_id']
    + ' OR id = ' + userPokemonRows[todo]['move3_id']
    + ' OR id = ' + userPokemonRows[todo]['move4_id'];;
    connection.query(sqlMove, function(err, moveRows) {
        console.log(todo);
        if(err) {
            console.log(this + err.code);
        }
        else {
            userPokemonRows[todo]['moves'] = moveRows;
            if(todo == 0) {
                callback(userPokemonRows);
            }
            else {
                loadMoveToPokemon(todo-1, userPokemonRows, connection, callback);
            }
        }
    });
}

 

posted on 2013-06-09 11:34  超级变便便  阅读(233)  评论(0编辑  收藏  举报