保存JavaScript Promise以备将来使用
我正在使用Node.js来构建服务器端RESTApi。当我自己测试时,节点运行良好。但当它真的存在时,它仍可能面临溢出问题。当有很多请求时,比如说有5个以上的子进程(spawn)同时工作,每个进程都会花费更长的时间,基本上会减慢一切 我的想法是检查当前进程是否低于某个限制(例如,一次限制为3个进程),如果超过限制,我将请求保存到一个数组中,每当当前进程低于限制时,我使用.shift()弹出数组中最旧的进程并处理它 然而,当谈到承诺时,它变得很困难,因为我不知道我们是否可以将承诺存储到数组中,或者我是否应该让过程暂停几秒钟,我认为这不是一个好主意 如果你想保持承诺并在将来将承诺返还给客户,通常的方式是什么 对不起,我没有说清楚。以下是我的疑问总结: 1.我们能保留一个承诺以备将来使用吗? 2.我们是否将它们保存在数组中? 3.我是否应该使用其他方法来兑现承诺,比如使用sleep()或简单地使用while循环来等待这个过程继续进行 谢谢大家!保存JavaScript Promise以备将来使用,javascript,node.js,promise,Javascript,Node.js,Promise,我正在使用Node.js来构建服务器端RESTApi。当我自己测试时,节点运行良好。但当它真的存在时,它仍可能面临溢出问题。当有很多请求时,比如说有5个以上的子进程(spawn)同时工作,每个进程都会花费更长的时间,基本上会减慢一切 我的想法是检查当前进程是否低于某个限制(例如,一次限制为3个进程),如果超过限制,我将请求保存到一个数组中,每当当前进程低于限制时,我使用.shift()弹出数组中最旧的进程并处理它 然而,当谈到承诺时,它变得很困难,因为我不知道我们是否可以将承诺存储到数组中,或者
当您实现正确的解决方案(排队并卸载到不同的服务)时,您可以创建一个承诺队列,在其中返回一个承诺,并在队列准备就绪后解析它 承诺本身就是一种代表未来价值的结构。在创建后的任何时候,当您调用
然后(cb)
时,它都会为您提供值。如果我使用loadash会有帮助吗?您是否考虑过在流程中使用承诺队列
包?是的,承诺一个简单的值,可以像其他任何程序一样传递。听起来您需要一个更强大的服务器,或者找到并修复性能瓶颈。仅仅排队请求通常不会有帮助——这些队列最终也会溢出。管理它们需要额外的处理能力和内存,因此通常最好尽快为它们提供服务。sleep
听起来像是一种同步阻塞方法,这与loop@Bergi我认为OP的意思是在承诺中睡觉“在承诺中”并不意味着“在背景中”。你根本不应该睡觉。所以在现实世界中,“子进程”通常在不同的服务器实例中?我实际上在后面使用child_进程来运行python。有更好的方法吗?在“现实世界”中,您通常会在容器中执行所有这些操作,而运行python将在从队列馈送的不同容器中运行—这样您可以“弹性地”扩展python进程实例的数量。
// 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;
}
}