Javascript函数可以更有效地处理并发异步函数
Javascript function to handle concurrent async function more efficiently
考虑以下内容:
- 每秒最多可有100个并发请求的web应用程序
- 当前,每个传入请求都会向端点发出http请求以获取一些数据(这可能需要5秒)
- 我只想发出一次http请求,即我不想对同一个端点进行并发调用,因为它将返回相同的数据
- 其想法是只有第一个请求才会进行http调用以获取数据
- 当此调用是"正在进行"时,后续请求将不会进行相同的调用,而是"等待"第一个正在进行的请求完成。
- 当对数据的初始http请求已响应时,它必须用数据响应所有调用。
- 我正在使用Bluebird promise来执行http请求的异步函数。
我想创建/使用某种通用方法/类来包装业务逻辑promise方法。这个通用方法/调用将知道何时调用实际的业务逻辑函数,何时等待inflight完成,然后在有响应时解析所有等待的调用。
我希望已经有一个节点模块可以做到这一点,但我想不出这种类型的实用程序会被称为什么。
类似于lodash-through/debounce的东西,但不完全相同。
如果它不存在,我可以自己写,但很难想出一个合理的名字。
如有任何帮助,我们将不胜感激。
您可以实现PromiseCache,例如:
module.exports = function request(url) {
if (caches[url]) return caches[url];
var promise = req(url);
return (caches[url] = promise);
};
var req = require('');
var caches = {};
编辑:
让我来解释一下:
这里不是关于缓存响应,而是关于缓存承诺。Nodejs是单线程的,也就是说,即使所有东西都是异步的,也没有并发的函数调用,在某个时间点,只运行一段代码。这意味着,将有人首先调用url为y.com/foo
的函数,缓存中不会有promise,因此它将触发GET请求并缓存并返回该promise。当有人立即用相同的url调用函数时,不会再触发请求,而是会返回该url的第一个promise,消费者可以订阅done/fail
回调。当响应准备好并且promise实现,并且有人使用相同的url发出请求时,它将再次取回缓存的promise,该promise已经准备好了。
Promise缓存是防止重复异步任务的好方法。
一个web应用程序只能有6个并发请求,因为这是浏览器的硬限制。旧的IE只能做2。所以,无论你做什么,这都是一个严格的限制。
通常,您应该在服务器端解决多路复用问题。
现在,对于你的实际问题,你所要求的缓存与承诺非常简单。
function once(fn) {
var val = null; // cache starts as empty
return () => val || (val = fn()); // return value or set it.
}
var get = once(getData);
get();
get(); // same call, even though the value didn't change.
现在,您可能需要添加一个到期策略:
function once(fn, timeout) {
var val = null, timer = null; // cache starts as empty
return () => val || (val = fn().tap(invalidate)); // return value and invalidate
function invalidate() {
clearTimeout(timer); // remove timer.
timer = setTimeout(() => val = null, timeout);
}
}
var get = once(getData, 10000);
如果失败,您可能还想取消缓存结果:
function once(fn, timeout) {
var val = null, timer = null; // cache starts as empty
return () => val ||
(val = fn().catch(e => value = null, Promise.reject(e)).tap(invalidate));
function invalidate() {
clearTimeout(timer); // remove timer.
timer = setTimeout(() => val = null, timeout);
}
}
由于最初的功能是一行代码,因此没有辅助程序。
您可以使用promise来防止重复请求同时
在nodejs中编写示例,您也可以在浏览器中使用此模式
const rp = require('request-promise'),
var wait = null;
function getUser(req, rep, next){
function userSuccess(){
wait = null;
};
function userErr(){
wait = null;
};
if (wait){
console.log('a wait');
}
else{
wait = rp.get({ url: config.API_FLIX + "/menu"});
}
wait.then(userSuccess).catch(userErr);
}
- 如何让 AJAX 函数处理提交表单
- Jquery onmouseover()函数处理动态html图像和span
- 如何在ajax调用完成之前停止函数处理
- 如何跨多个函数处理Promise
- JavaScript 函数中的 JQuery 函数 :: 处理.js.
- 覆盖 jquery .load() 函数 - 处理回调
- 调用 Javascript 函数处理表单后,HTML 表单未打印到浏览器
- 如果选中单选按钮,则调用函数处理程序
- 我们如何在错误的资源请求的情况下使用 XMLHttpRequest 函数处理程序
- Javascript 对象或函数处理程序的新函数
- 函数处理 mootools.floor 不工作
- 如何将函数处理程序从控制器传递到 AngularJs 中的指令隔离范围
- Javascript闭包和前后函数处理程序
- position()被当作函数处理
- 存储/导入变量&函数处理(JS)
- 如何使用Out回调函数处理JQueryAjax结果
- 在事件上填充数组,并在事件函数处理程序外部访问它
- 如何在JavaScript中从嵌套函数处理程序返回
- 用一个函数处理多个事件
- 通过单个javascript函数处理两个表单