首页 > 开发 > NodeJS > 正文

js匿名函数内部如何才能改变函数外部的局部变量值?

2017-09-08 17:11:01  来源:网友分享

1、mysqljs的查询语句,最后一个参数是匿名函数,这个匿名函数为什么不能改变函数体外面的局部变量?如果要改变,如何做:
2、代码如下:

function checkExist(str) {  let rt=0;  if ((typeof(str)!='string' )||(str.length <= 1)) {rt=3 ;}  let query = connection.query(    "SELECT count(1) AS solution from taxlaw_chinatax_js where url like ? ",    [str],    (error, results, fields) => {      if (error) throw error;      let cou = results[0].solution;      console.log(cou);      if ( cou >= 1) {        //console.log("检查数据已经采集过,忽略。");        rt= 2;      } else if (cou < 1) {        //console.log("检查此条不存在,添加开始:" + str);        rt= 1;      }    }  );  //console.log('检查数据库状态错误');  //console.log(query.sql);  return rt;}

3、匿名函数(error, results, fields) => {}内部的rt值在超出函数的作用域之后,rt的值全部都是0。
实际上应该根据str的数据库查询结果,有的rt是2,有的rt是1,不应该统统是0.
也就是说,匿名函数改变不了外部变量rt的值。
想要改变,如何做?

4、试过直接在匿名函数内部直接返回rt值,也是无用的。代码如下:

function checkExist(str) {  var rt=0;  if ((typeof(str)!='string' )||(str.length <= 1)) {return 3 ;}  connection.query(    "SELECT count(1) AS solution from taxlaw_chinatax_js where url like ? ",    [str],    (error, results, fields) => {      if (error) throw error;      let cou = results[0].solution;      console.log(cou);      if ( cou >= 1) {        //console.log("检查数据已经采集过,忽略。");        return 2;      } else if (cou < 1) {        //console.log("检查此条不存在,添加开始:" + str);        return 1;      }    }  );  //console.log('检查数据库状态错误');  //console.log(query.sql);  return 0;}

这种情况下,返回的都是0。匿名函数只能返回一层,不能返回两层。

5、改成如下代码:

function checkExist(str) {  var rt=0;  if ((typeof(str)!='string' )||(str.length <= 1)) {return 3 ;}  rt = connection.query(    "SELECT count(1) AS solution from taxlaw_chinatax_js where url like ? ",    [str],    (error, results, fields) => {      if (error) throw error;      let cou = results[0].solution;      console.log(cou);      if ( cou >= 1) {        //console.log("检查数据已经采集过,忽略。");        return 2;      } else if (cou < 1) {        //console.log("检查此条不存在,添加开始:" + str);        return 1;      }    }  );  //console.log('检查数据库状态错误');  //console.log(query.sql);  return rt;}

返回的是个object,不是具体的数字。

如何做?

解决方案

数据库操作是异步操作,无法直接return结果的,
如果你能使用es7,可以用async, await来模拟同步

function checkExist(str) {  return new Promise((resolve, reject) =>{    let rt = 0;    if ((typeof(str)!='string' )||(str.length <= 1)) {        resolve(3);        return;    }    connection.query(      "SELECT count(1) AS solution from taxlaw_chinatax_js where url like ? ",      [str],      (error, results, fields) => {        if (error) throw error;        let cou = results[0].solution;        console.log(cou);        if ( cou >= 1) {          resolve(2); //返回结果        } else if (cou < 1) {          resolve(1); //返回结果        } else {          reject(); //未知结果        }      }    );  });} let process = async function() {    try {        let rt = await checkExist("str");        console.log("rt:%s", rt);    } catch(e) {        console.log("unknow rt");    }}process();

es5的话只能通过回调获得值:

function checkExist(str, callback) {  var rt=0;  if ((typeof(str)!='string' )||(str.length <= 1)) {      callback(3);      return;  }  connection.query(    "SELECT count(1) AS solution from taxlaw_chinatax_js where url like ? ",    [str],    function (error, results, fields) {      if (error) throw error;      var cou = results[0].solution;      console.log(cou);      if ( cou >= 1) {        callback(2);      } else if (cou < 1) {        callback(1);      } else {        callback("unknown");      }    }  );}checkExist("str", function(rt) {    console.log("rt:%s", rt);}