NodeJs流程

时间:2018-08-07 07:20:06

标签: node.js

我最近开始研究nodeJ。但是,在不同的页面上使用全局或var关键字变量的单线程概念错将其混淆,而使用不同的页面则需要使用它们。下面是我的代码。

    var express = require("express");
    var app = express();
    var mysql = require("mysql");
    var comm_fun = requre("./common_functions");
    var global_res = ''; // variable to send the reponse back to browser from any function
    var global_req = '';// variables to save request data


    app.listen(1234,function(req,res){

        console.log("server started");
        global_res = res;
        global_req = req;
        mysql = '';// code to have mysql connection in this variable
    });

现在,因为我可以在包含的不同文件中使用mysql,global_res和global_req变量。但是这些会影响另一个请求的值,因为它们是全局的。

例如, 请求1的“ global_req”值为1,

同时出现请求2

请求2的“ global_req”值为2

这两个请求将在任何时间冲突。可以在任何时间点将“ global_req”从1覆盖为2,因为第二个请求已到达。或两者都是不同的请求,并且在任何时间都不会冲突。

谢谢

1 个答案:

答案 0 :(得分:0)

是的,这是一个非常简单的场景:

  1. 请求1进入,将全局ID设置为1
  2. 请求1然后执行一些IO绑定操作(例如,数据库查询)
  3. 同时出现请求2并将全局ID设置为2
  4. 与IO绑定的操作已完成,请求1继续,但全局ID现在为2,而不是1

仅在您的应用程序完全受CPU约束的情况下,才可以使用有关Node是单线程的参数,但是,鉴于大多数Node应用程序受 IO 约束,因此它们实际上是多线程的,穿线。问题在于,我们无法保证回调返回的顺序,并且牢记创建竞争条件非常简单,例如

let global_id = 0;
...
app.use(() => global_id++);
app.post('/create', async (req, res) => {
  try {
    const exists = db.query(`SELECT id FROM table WHERE id = ${global_id}`);
    if (!exists) {
      db.query(`INSERT INTO ....`);
    }
  } catch (e) {
    return next(e);
  }
});

如果2个请求同时到达/create端点,则非常不太可能都成功(至少正确)。