新人自学遇到的nodejs的执行顺序问题
 var findTalk = function(id){
 connection.query('SELECT id,content,date,userimg,username FROM talk'+id, function(err, rows, fields) {
  if (err)
    throw err;
  if (rows) {
    for (var i = 0; i < rows.length; i++) {
      var talk = {
        id: 0,
        content: "",
        date: '',
        userimg: '',
        username: ''
      };
      talk.id = rows[i].id;
      talk.content = rows[i].content;
      talk.date = rows[i].date.toString().substr(0, 21);
      talk.userimg = rows[i].userimg;
      talk.username = rows[i].username;
      talks.push(talk);

    }
console.log('1');
  }

});

};

app.get('/talk/', function(req, res) {

  var id = req.query.id;
  findTalk(id);
for (var i = 0; i < talks.length; i++) {
  json[i] = talks[i];
}
  console.log('2');
  res.send(json);
});

返回到客户端的json数组总是空,执行后也是在控制台先输出2,后输出1,明明findData(id)在前,为什么先输出了2,而不是先输出findData里的1

2个回答

由于函数回调,你可以这么理解 js 是单线程,但是异步
单线程,就是会从头执行到尾,但是由于有异步,回调函数的存在.才能使程序高效.
这里先查数据库,一个异步函数,查数据库需要时间(数据库查找,),所以执行后,就放一个监听器,也就是回调函数,
js代码继续执行下面的console.log(2),等监听器,监听到数据库返回了数据时,才会执行,数据库查询回调函数里面的事情,也就是输出1;
所以上面的事情是这样发生的,
1.先查数据库 ,-->监听回调,等待数据库响应
2.继续执行console.log(2);
3.数据库响应数据了,继续执行.
注意一下执行队列,回调函数只是把回调放到当前队列的最前面,而不是立即执行.例如前面一个大循环需要几秒钟,那么回调函数就需要等待执行完,才会继续执行.
js 理解回调,和处理好回调,基本上没有什么特别大的难度

query是异步执行的,执行for的速度几乎忽律,然后就直接执行console.log(2)了才会执行到异步查询回掉中的log 1,这个和ajax异步查询一个意思,要用回掉的形式来获取查询返回,要不talks永远得不到正确的查询返回值


    var findTalk = function (id,callback) {///////////////
        connection.query('SELECT id,content,date,userimg,username FROM talk' + id, function (err, rows, fields) {
            if (err)
                throw err;
            if (rows) {
                for (var i = 0; i < rows.length; i++) {
                    var talk = {
                        id: 0,
                        content: "",
                        date: '',
                        userimg: '',
                        username: ''
                    };
                    talk.id = rows[i].id;
                    talk.content = rows[i].content;
                    talk.date = rows[i].date.toString().substr(0, 21);
                    talk.userimg = rows[i].userimg;
                    talk.username = rows[i].username;
                    talks.push(talk);

                }
                console.log('1');

                callback()///////////
            }

        });

    };

    app.get('/talk/', function (req, res) {

        var id = req.query.id;
        findTalk(id, function () {//////////////
            for (var i = 0; i < talks.length; i++) {
                json[i] = talks[i];
            }
            console.log('2');
            res.send(json);
        });
    });
Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!
立即提问