微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

保存JavaScript Promise以供将来使用

我正在使用Node.js构建服务器端RESTApi.当我自己测试时,Node工作正常.但是,当它确实存在时,仍然可能会遇到溢出问题.当有很多请求时,例如说有5个以上的child_process(spawn)同时工作,则每个进程花费的时间更长,基本上会减慢一切.

我的想法是检查当前进程是否低于某个限制(例如一次限制为3个进程),如果超过该限制,则将请求保存到数组中,并且每当当前进程低于该限制时,我使用.shift()来弹出数组中最旧的一个并进行处理.

但是,当涉及到Promises时,将变得很困难,因为我不知道我们是否可以将Promise存储到数组中,或者我是否应该让过程暂停几秒钟,我认为这不是一个好主意.

如果您要保留承诺并在将来将承诺退还给客户,通常的方法是什么?

抱歉,如果我没有说清楚.以下是我的疑问摘要
1.我们可以保留将来的诺言吗?
2.我们是否将它们保存在数组中?
3.我是否应该使用其他方法来保持承诺,例如使用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;
    }
} 

代码从仍然是WIP的bluebird-api提升.

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,并在队列准备就绪时稍后对其进行解析.

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐