javascript - 如何在 Mean Stack 中运行子进程

标签 javascript angularjs node.js mongodb express

我有一个使用 Nodejs、AngularJS 和 ExpressJS 的 Mean 应用程序。

在这里,我从 Angular Controller 调用了我的服务器,如下所示

Angular Controller.js

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

         --
         --     
        }

Server.js中如下

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

在这里,我正在上面代码中的帖子示例中使用 mongodb 进行操作。

在这里,我对如何进行计算部分感到震惊,就像我有一个需要一些时间(假设 1 小时)才能完成的大型计算。因此,从客户端,我将从我的 Angular Controller 触发该计算。

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

我在nodejs中看到过这个子进程,但我不明白如何从 Controller 的子进程触发或执行它,如果它在app.post中收到请求,那么是否可以访问其他页面。

编辑:

我计划在 Spawn 中创建一个 child_process,但继续上述操作时遇到另一个问题。

让我们考虑应用程序包含 3 个用户,并且有 2 个用户同时访问该应用程序。 我的情况是,如果第一个人触发了 child_process,将其命名为第一个操作,并且它正在处理中,而此时第二个人需要触发该进程,将其命名为第二操作,因为他也需要计算。 这是我的问题

  1. 如果另一个人启动了生成命令,会发生什么情况。如果它挂起或保留在队列中或两者并行执行。
  2. 如果第二个操作在队列中,则何时开始该操作。
  3. 如果第二个操作在队列中,那么我如何知道某个时间点有多少个操作在队列中

谁能帮忙解决一下吗?

最佳答案

注意:问题已编辑 - 请参阅下面的更新。

您几乎没有选择。

最直接的方法是从 Express Controller 中生成子进程,一旦计算完成,它就会将响应返回给客户端,但如果需要很长时间,那么您可能会遇到套接字超时等问题。这不会阻塞您的服务器或客户端(如果您不在服务器上使用“同步”功能并在客户端上使用同步 AJAX),但您会遇到连接挂起这么长时间的问题。

另一种选择是使用 WebSocket 或 Socket.io 来处理这些请求。客户端可以向服务器发布一条消息,表示它希望开始一些计算,服务器可以生成子进程,执行其他操作,当子进程返回时,只需将消息发送给客户端。这样做的缺点是一种新的通信方式,但至少不会出现超时问题。

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

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

  • 生成
  • 执行
  • execFile
  • fork

来自核心child_process模块。只要确保永远不要使用任何名称中带有“Sync”的函数来执行您想要执行的操作,因为这些函数会阻止您的服务器在等待子进程完成的整个时间内处理其他请求 - 在您的情况下可能是一个小时,但即使是一秒钟,它仍然可能完全破坏并发性。

查看文档:

更新

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

#!/bin/sh
sleep 5
date -Is

等待 5 秒并打印当前时间。现在考虑这个示例 Node 应用程序:

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 秒的间隔收到一个又一个响应,则操作将排队。如果您同时收到具有或多或少相同时间戳的所有响应,那么这些响应都是并行运行的。

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

关于javascript - 如何在 Mean Stack 中运行子进程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43258245/

相关文章:

javascript - 是否可以从刚刚从列表中删除的项目中获取选择列表的名称

javascript - 在条形图中显示多维数组(在 JavaScript 中)?

javascript - 在angulajs中转换java对象中的json时,获取嵌套异常是com.fasterxml.jackson.databind.JsonMappingException

javascript - Selenium 单击可以工作,但无法获取下一个窗口上的元素

javascript - 扩展 Error 对象时是否需要 super(originalError)?

node.js - 如何使用multer和NodeJS将图像上传到GCS存储桶?

javascript - Angular 动画

javascript - 在 document.ready() 之后加载 jquery 函数

java - 通过 Rest 将字符串返回方法转换为 jSON

javascript - NodeJs,connection.query 中的 if 语句