如何在Mean Stack

时间:2017-04-06 14:34:01

标签: javascript angularjs node.js mongodb express

我有一个使用nodejs,angularjs和expressjs的Mean应用程序。

这里我从角度控制器调用了我的服务器,如下所示

Angular Controller.js

     $http.post('/sample', $scope.sample).then(function (response) {

         --
         --     
        }

并在 Server.js 中,如下所示

app.post('/sample', userController.postsample);

在这里,我正在使用mongodb对上面代码中的 post sample 进行操作。

在这里,我对如何进行计算部分感到震惊,就像我有一个很大的计算需要花费一些时间(假设1小时)才能完成。所以从客户端我将从我的角度控制器触发计算。

我的问题是计算应该单独运行,以便其他页面的其他UI和操作不应该被中断。

我在nodejs中看到了这个子进程,但我不明白如何从控制器的子进程触发或执行该进程,如果它在 app.post 中得到请求则可以访问其他页面。

修改

我计划在Spawn中执行一个child_process但是我还有另外一个问题仍在继续。

让我们考虑应用程序包含3个用户和2个用户同时访问该应用程序。   我的情况是,如果第一个人触发了child_process,将其命名为first operation并且它正在进行中,当第二个人需要触发进程时,将其命名为2nd operation,因为他还需要计算。  我的问题是

  1. 如果其他人启动了spawn命令会发生什么。如果它挂起或保持在队列中或两者都执行并行。
  2. 如果第二个操作在队列中,那么它何时开始操作。
  3. 如果第二个操作在队列中,那么我怎么知道在一个时间点有多少人在队列中
  4. 任何人都可以帮忙解决。

1 个答案:

答案 0 :(得分:1)

注意:问题已修改 - 请参阅以下更新。

你没有多少选择。

最直接的方法是从Express控制器生成子进程,这会在计算完成后将响应返回给客户端,但是如果花了这么长时间,则可能会出现套接字超时等问题。不阻止你的服务器或客户端(如果你没有在服务器上使用“同步”功能和客户端上的同步AJAX)但你会遇到连接挂起这么久的问题。

另一种选择是对这些请求使用WebSocket或Socket.io。客户端可以向服务器发送一条消息,它希望开始一些计算,服务器可以生成子进程,做其他事情,当子进程返回时只是将消息发送给客户端。这样做的缺点是一种新的沟通方式,但至少不存在超时问题。

要了解如何将WebSocket或Socket.io与Express结合使用,请参阅此答案,其中包含WebSocket和Socket.io的示例 - 实际上非常简单:

无论哪种方式,要生成子进程,您都可以使用:

  • spawn
  • exec
  • execFile
  • fork
来自核心child_process模块的

。只需确保从不使用名称中包含“同步”的任何功能,因为这些功能会阻止您的服务器在整个等待孩子完成的时间内提供其他请求 - 在你的情况下,这可能是一个小时,但即使它是一秒钟,它仍然可能完全破坏并发。

参见文档:

更新

编辑问题的一些更新。考虑这个示例shell脚本:

#!/bin/sh
sleep 5
date -Is

等待5秒钟并打印当前时间。现在考虑这个示例Node app:

let child_process = require('child_process');

let app = require('express')();

app.get('/test', (req, res) => {
  child_process.execFile('./script.sh', (err, data) => {
    if (err) {
      return res.status(500).send('Error');
    }
    res.send(data);
  });
});

app.listen(3344, () => console.log('Listening on 3344'));

或使用ES2017语法:

let child_process = require('mz/child_process');

let app = require('express')();

app.get('/test', async (req, res) => {
  try {
    res.send((await child_process.execFile('./script.sh'))[0]);
  } catch (err) {
    res.status(500).send('Error');
  }
});

app.listen(3344, () => console.log('Listening on 3344'));

它为GET /test上的请求运行该shell脚本并返回结果。

现在同时开始两个请求:

curl localhost:3344/test & curl localhost:3344/test & curl localhost:3344/test &

看看会发生什么。如果返回的时间相差5秒,并且您以5秒的间隔获得一个接一个的响应,那么操作将排队。如果您同时获得所有响应的时间戳大致相同,那么这些响应将并行运行。

有时最好进行这样的实验,看看会发生什么。