- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
我正在使用 Node.js 构建服务器端 RESTApi。当我自己测试时,Node 工作正常。但是当它真的在那里时,它仍然可能面临溢出问题。当有很多请求时,比如有超过 5 个 child_process (spawn) 同时工作,每个进程花费更长的时间,基本上减慢一切。
我的想法是检查当前进程是否低于某个限制(比如,一次限制为 3 个进程),如果超过限制,我将请求保存到一个数组中,每当当前进程低于限制,我使用 .shift() 弹出数组中最旧的一个并处理它。
然而,当涉及到 Promise 时,它变得困难,因为我不知道我们是否可以将 Promise 存储到数组中,或者我是否应该让进程暂停几秒钟,我认为这不是好主意。
如果你想保持 promise 并在未来将 promise 返回给客户,通常的做法是什么?
对不起,如果我没有说清楚。下面总结一下我的疑惑:1. 我们可以保存一个 promise 以备将来使用吗?2.我们是否将它们保存在数组中?3. 我是否应该使用其他方法来保持 promise ,例如使用 sleep() 或只是一个 while 循环来等待此过程继续进行?
谢谢!
最佳答案
say there are more than 5 child_process (spawn) working at the same time, each process is taking longer time, basically slow down everything.
在现实世界的部署中——你不会以这种方式处理带有子任务的 CPU 密集型任务——你会使用一个健全的并发数据结构(比如 mqtt 或数据库上的队列)并将工作分配给你部署的工作人员然后将其发送回服务器。
原因是服务器总是会宕机——而你要防止部分工作。
My idea is to check if the current process is below a certain limit (like, limit to 3 processes at a time), if it exceed the limit, I save the requests into an array, and whenever the current processes is below the limit, I use .shift() to pop the oldest one in the array and process it.
这是执行此操作的代码,我请求您阅读第一点并且不要在生产中使用该代码,而是在您的部署中限制它(例如,如果您使用 AWS 将规模限制为 3 个实例):
// lifted from my bluebird-api project
function throttle(fn, concurrency = 20, Promise) {
// create an array of workers as resolved promises
const workers = Array(concurrency).fill(Promise.resolve());
const work = []; // pending work
return function (...args) {
// when there is work, pull the next worker
const worker = workers.pop();
if (worker === undefined) { // if there is no pending worker
let resolve, reject;
// store the promise for the result
const promise = new Promise((res, rej) => {
resolve = res;
reject = rej;
});
// and add it to the queue
work.unshift({ args, resolve, reject, promise });
return promise;
}
// after the worker is ready, call the function
worker = worker.then(() => (fn(...args), null));
worker.then(function pump() {
if (work.length) { // after you're ready
const {resolve, reject, args} = work.pop();
// continue draining the queue
worker = worker.then(() => fn(...args)).then(resolve, reject).then(pump);
} else { // or declare ready
workers.push(worker);
}
return null;
});
return worker;
}
}
代码摘自bluebird-api这仍然是 WIP。
What is the normal way if you want to hold a promise and return the promise to client in future?
是的,它完全是一个受支持的案例 - 它不会泄漏内存并且是安全的(在现代 promise 实现中)。虽然再次 - 这是一个 XY 问题 - 你不应该在 Node 服务器上以这种方式分配工作。
当您实现正确的解决方案(排队和卸载到不同的服务)时,您可以创建一个 promise 队列,您可以在其中返回一个 promise 并稍后在队列准备就绪时解决它。
关于javascript - 保存 JavaScript Promise 以备将来使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45037180/
我是一名优秀的程序员,十分优秀!